Клас TPicture
Клас TFont Клас Треn Клас TBrush Клас TCanvas Клас TGraphic Клас TPicture 8.Графічний формат JPEG. Клас TJPEGImage
"Одне зображення коштує тисячі слів", — говорив старокитайський імператор Сун; його слова вірні і в наші часи. 80% інформації мозок людини отримує по зоровому каналу, і не дивно, що програмісти прагнуть додати зовнішньому вигляду своїх програм максимум привабливості. Тому в Delphi із самого початку з'явилися розвинені засоби для роботи з графічними можливостями Windows. Цьому набору об'єктів і присвячена дана лекція.
Графічні інструменти Delphi
Розробники Delphi приділили велику увагу можливостям роботи з діловою графікою: простота і зручність її використання безпосередньо позначаються на простоті і зручності створених приложень. Замість нетрів графічного інтерфейсу Windows розробник отримав декілька інструментів, наскільки зрозумілих, так же і могутніх. У стандартному графічному інтерфейсі Windows (GDI) основою для малювання служить дескриптор контексту пристрою ніс і пов'язані з ним шрифт, перо і кисть. До складу VCL входять об'єктно-орієнтовані надбудови над останніми, призначенням яких є зручний доступ до властивостей інструментів і прозора для користувача обробка всіх їх змін. Обов'язковим для будь-якого об'єкту, пов'язаного з графікою в Delphi, є подія:
property OnChange: TNotifyEvent;
Її обробник викликається всякий раз, коли міняються якісь характеристики об'єкту, що впливають на його зовнішній вигляд. Клас TFont
Клас інкапсулює шрифт Windows. У Delphi допускаються тільки горизонтально розташовані шрифти. У конструкторі об'єкту за умовчанням приймається шрифт System, кольори ciwindowText і розміром 10 пунктів.
Властивості класу TFont
Установка цих властивостей вручну, як правило, не потрібна. Якщо ви хочете змінити шрифт для якогось компоненту, скористайтеся компонентом TFontDialog. У нім можна і поміняти властивості, і відразу побачити результат, що вийшов, на тестовому написі; потім вибраний шрифт привласнюється властивості Font потрібного компоненту: if FontDialogl.Execute then Editl.Font:= FontDialogl.Font; Якщо ви хочете, не закриваючи діалог, побачити результат приложення шрифту на вашому тексті, включіть опцію fdApplyButton у властивості Options об'єкту TFontDialog і напишіть для нього обробник події onApply. При цьому в діалоговому вікні з'явиться кнопка Apply, no натисненні якої (подія OnApply) можна змінити параметри шрифту. Клас Треn
Цей клас інкапсулює властивості пера GDI Windows. У конструкторі за умовчанням створюється безперервне (pssolid) чорне перо шириною в один піксел.
Властивості класу TPen
На жаль, пунктирні і штрихпунктирні лінії (стилі psDash, psDot, psDashDot, psDashDotDot) можуть бути встановлені тільки для ліній одиничної товщини. Товщі лінії повинні бути суцільними — таке обмеження існує в Windows. Операція pmNotXor підходить для малювання ліній, що переміщаються, або фігур, наприклад, при виділенні мишею якої-небудь області. Якщо ви двічі намалюєте одну і ту ж фігуру таким пером, то після першого разу вона з'явиться, після другого — повністю зітреться. Клас TBrush Цей клас інкапсулює властивості кисті — інструменту для заливки областей. Коли створюється екземпляр цього класу, спочатку використовується біла суцільна (style=bsSolid) кисть. Властивості класу TBrush
Шрифт, перо і кисть не можуть використовуватися самостійно. Вони є складовими частинами спеціального класу, який і буде зараз розглянутий. Клас TCanvas Цей клас — серцевина графічної підсистеми Delphi. Він об'єднує в собі і "полотно" (контекст конкретного пристрою GDI), і "робочі інструменти" (перо, кисть, шрифт), і навіть "підмайстрів" (набір функцій по малюванню типових геометричних фігур). Називатимемо його канвою. Канва не є компонентом, але вона присутня як властивість в багатьох інших компонентах, які повинні уміти намалювати себе і відобразити яку-небудь інформацію. Ті, хто знайомий з графікою Windows, дізнаються в TCanvas об'єктно-орієнтовану надбудову над контекстом пристрою Windows (Device Context, DC). Дескриптор пристрою, над яким "побудована" канва, може бути затребуваний для різних низькорівневих операцій. Він задається властивістю: property Handle: HDC; Для малювання канва включає шрифт, перо і кисть: property Font: TFont; property Pen: TPen; property Brush: TBrush; Крім того, можна малювати і поточковий, діставши доступ до кожного піксела. Значення властивості: property Pixels[X, Y: Integer]: TColor; відповідає кольору крапки з координатами X, Y. Необхідність отмальовувати кожну крапку виникає нерідко. Проте, якщо потрібно модифікувати все або хоч би багато точок зображення, властивість Pixels треба відразу відкинути — настільки воно неефективне. Набагато швидше редагувати зображення за допомогою властивості scanLine об'єкту TBitmap;. Канва містить методи-надбудови над всіма основними функціями малювання GDI Windows і властивості, які приведені в табл. 10.4 і 10.5. При їх розгляді майте на увазі, що всі геометричні фігури малюються поточним пером. Ті з них, які можна закрашувати, закрашуються за допомогою поточної кисті. Кисть і перо при цьому мають поточний колір. Методи класу TCanvas
Властивості класу TCanvas
Де ж знайти ту канву, на якій належить малювати? По-перше, нею забезпечені всі нащадки класів TGraphicControl і TCustomControl, тобто майже всі візуальні компоненти з Палітри компонентів; у тому числі і форма. По-друге, канву має растрова картинка (клас TBitmap); ви можете писати і малювати не на порожньому місці, а на готовому зображенні (про цьому див. нижче в разд. "Клас TBitmap" даного розділу). Але іноді потрібно малювати і прямо на екрані. В цьому випадку доведеться удатися до використання функцій API. Крім графічних примітивів, таких як лінії і фігури, на канві можна розмістити готові зображення. Для їх опису створений клас TGraphic.
Клас TGraphic Канва, перо, кисть і шрифт потрібні, щоб намалювати свою картинку. Щоб завантажити готову, необхідні об'єкти, що "розуміють" графічні формати Windows. Абстрактний клас TGraphic є батьківським для трьох видів зображень, загальноприйнятих в графіці Windows, — значка (компонент TIcon), метафайлу (компонент TMetafile) І растрової картинки (компонент TBitmap). Четвертим нащадком TGraphic є TJPEGImage — стисла растрова картинка у форматі JPEG. Працюючи над приложенням в Delphi, ви ніколи не створюватимете об'єкти класу TGraphic, але змінній цього типу ви можете привласнювати покажчик на будь-який з перерахованих класів-нащадків. Метод: procedure Assign(Source: Tpersistent); перевизначає однойменний метод предка, допускаючи поліморфне привласнення графічних об'єктів. Завантаження і вивантаження графіки в потік здійснюють методи: procedure LoadFromStream(Stream: TStream); procedure SaveToStream(Stream: TStream); а завантаження і вивантаження у файл — методи: procedure LoadFromFile(const Filename: string); procedure SaveToFile(const Filename: string); Ці методи створюють відповідний файловий потік і потім викликають методи LoadFromStream/SaveToStream. Два методи здійснюють взаємодію з буфером обміну Windows: procedure LoadFromClipboardFormat(AFormat: Word; AData: THandle; APalette: HPALETTE); procedure SaveToClipboardFormat(var AFormat: Word; var AData: THandle; var APalette: HPALETTE); Тут AFormat — використовуваний графічний формат; AData і APalette — дані і палітра (якщо вона потрібна). Нащадок повинен мати свій формат уявлення в буфері обміну і уміти обробляти дані, представлені в нім. Завантаження великих графічних файлів може продовжуватися дуже довго. Щоб скрасити користувачеві очікування, програміст може обробити подію OnProgress! type TProgressStage = (psStarting, psRunning, psEnding); TProgressEvent = procedure (Sender: TObject; Stage: TProgressStage; PercentDone: Byte; RedrawNow: Boolean; const R: TRect; const Msg: string) of object; property OnProgress: TProgressEvent;
Воно викликається графічними об'єктами під час тривалих операцій. Параметр stage означає стадію процесу (начало/протекание/завершение), а PercentDone — відсоток зробленої роботи. Відразу обмовимося, що не всі з тих об'єктів, які будуть нами описані, викликають обробник події OnProgress.
Властивість: property Empty: Boolean; встановлюється в значення True, якщо графічний об'єкт порожній (у нього не завантажені дані). Висота і ширина графічного об'єкту задаються властивостями: property Height: Integer; property Width: Integer; Для кожного дочірнього типу ці параметри обчислюються своїм способом. Нарешті, властивість: property Modified: Boolean; показує, чи модифікувався даний графічний об'єкт. Ця властивість встановлюється в значення True усередині обробника події OnChange. Багато графічних об'єктів при отрисовке повинні бути прозорими. Одні з них прозорі завжди (значок, метафайл), інші — залежно від значення властивості property Transparent: Boolean;
Клас TPicture Це клас-надбудова над TGraphic, точніше — над його нащадками. Він має поле Graphic, яке може містити об'єкти класів TBitmap, Ticon, TMetafile і TJPEGimage. Призначення класу TPicture — управляти викликами відповідних методів, приховуючи при цьому клопіт з визначенням типу графічного об'єкту і деталі його реалізації. Крім того, на рівні TPicture визначені можливості реєстрації і використання інших — визначених користувачем — класів графічних об'єктів, породжених від TGraphic. Доступ до графічного об'єкту здійснюється за допомогою властивості: property Graphic: TGraphic; Якщо графічний об'єкт має один з трьох зумовлених типів, то до нього можна звернутися і як до однієї з властивостей: property Bitmap: TBitmap; property Icon: Ticon; property Metafile: TMetafile; Звертаючись до цих функцій, потрібно бути обережним. Якщо в полі Graphic зберігався об'єкт одного класу, а зажадався об'єкт іншого класу, то колишній об'єкт знищується, а замість нього створюється порожній об'єкт необхідного класу. Наприклад: Image1.Picture.LoadFromFile('myicon.ico'); //Создан і завантажений об'єкт класу Ticon MyBitmap:= Image1.Picture.Bitmap; // колишній Ticon знищується Якщо ж ви описали свій клас (допустимо, TGIFImage), то до його методів і властивостей слід звертатися так: (Graphic as TGIFImage).MyProperty:= MyValue;
Графічний формат JPEG. Клас TJPEGImage У 1988 році був прийнятий перший міжнародний стандарт стиснення нерухомих зображень. Він був названий на ім'я груп, яка над ним працювала — JPEG (Joint Photographic Expert Group). Річ у тому, що стандартні архіватори (ZIP, ARJ) і традиційні алгоритми стиснення у форматах GIF, TIFF і PCX не можуть достатньо сильно стиснути півтонову або кольорову картинку (типу фотографії) — максимум в 2—3 рази. Застосований в JPEG алгоритм дозволяє досягти стиснення в десятки разів — правда, при цьому зображення піддається необоротному спотворенню, і з нього пропадає частина деталей. Безглуздо (і шкідливо!) піддавати зберіганню у форматі JPEG креслення, малюнки, а також будь-які зображення з малим числом градацій — він призначений саме для зображень фотографічної якості. Підтримка формату JPEG реалізована в Delphi за допомогою класу TJPEGImage, який є нащадком класу TGraphic. До такого об'єкту пред'являються двоякі вимоги. З одного боку, він повинен підтримувати стиснення даних для запису на диск. З іншої — розпаковані дані у форматі DIB, щоб на вимогу системи відмалювати їх. Тому об'єкт класу TJPEGImage може зберігати обидва види даних, а також проводити їх взаємні перетворення, тобто стиснення і розпаковування. Для цього в нім передбачені методи: procedure Compress; procedure DIBNeeded; procedure JPEGNeeded; Рекомендується викликати метод DIBNeeded заздалегідь, перед отрисовкой картинки — це прискорить процес її виводу на екран. Крім того, корисно використовувати метод Assign, який дозволяє помістити в клас TJPEGimage об'єкт TBitmap і навпаки: MyJPEGImage.Assign(MyBitmap); MyBitmap.Assign(MyJPEGImage); При цьому відбувається перетворення форматів. Властивості TJPEGimage можна умовно розділити на дві групи: використовувані при стисненні і при розпаковуванні. Найважливішим з властивостей, потрібних при стисненні, є compressionQuality: type TJPEGQualityRange = 1..100; property CompressionQuaiity: TJPEGQualityRange; Воно визначає якість зображення, що стискається, і його розмір. При малих значеннях цієї властивості файли виходять дуже маленькими, але з великими спотвореннями (нагадаємо, що стандарт JPEG передбачає стиснення з втратами якості). При значеннях, близьких до 100, втрати непомітні, але і розмір файлу при цьому максимальний. Компонент TImage Цей компонент служить надбудовою над класом TPicture і замикає всю ієрархію графічних об'єктів VCL. Саме на його поверхні і відображатимуться графічні об'єкти, що містяться у властивості: property Picture: TPicture; Як канва компоненту (властивість canvas) використовується канва об'єкту з властивості Picture.Graphic, але тільки якщо поле Graphic посилається на об'єкт класу TBitmap. Якщо це не так, то спроба звернення до властивості викличе виняткову ситуацію EinvaiidOperation, оскільки малювати на метафайлі або значку не можна. Наступні три властивості визначають, як саме графічний об'єкт розташовується в клієнтській області компоненту: · property AutoSize: Boolean; Означає, що розміри компоненту настроюються по розмірах графічного об'єкту, що міститься в нім. Встановлювати його в значення True потрібно перед завантаженням зображення з файлу або буфера обміну. · property Stretch: Boolean; Якщо ця властивість встановлена в значення True, то зображення "натягається" на клієнтську область, при необхідності зменшуючи або збільшуючи свої розміри. Якщо воно встановлене в False, то грає роль наступну властивість Center. · property Center: Boolean; Якщо ця властивість встановлена в значення True, зображення центрується в межах клієнтської області. Інакше воно розташовується в її верхньому лівому кутку. Програму для проглядання зображень в середовищі Delphi можна створити по наступному алгоритму: 1. Помістіть на форму наступні компоненти: область прокрутки TScrollBox, на неї — компонент Timage (їх верхні ліві кути повинні співпадати), будь-яку кнопку (наприклад, TButton) і діалог відкриття файлів TOpenPictureDialog. 2. Підключите до головного модуля створюваного приложення модуль JPEG (у пропозиції uses); властивість AutoSize компоненту Timage встановите в значення True. 3. Двічі клацніть мишею на кнопці. У обробнику події onClick, що з'явився, напишіть такий код: procedure Tform1.BitBtn1Click(Sender: TObject); begin OpenPictureDialogl.Filter:= GraphicFilter(TGraphic); if OpenPictureDialogl.Execute then Image1.Picture.LoadFromFile (OpenPictureDialog1.FileName); end;
Контрольні запитання 1. Яка подія є обов'язковою для будь-якого об'єкту, пов'язаного з графікою в Delphi. 2. Яка функція к ласу TFont та його основні властивості. 3. Якій клас інкапсулює властивості пера GDI Windows. 4. Які функції класу TBrush та основні властивості. 5. Клас TСanvas та його методи.
Література:
|