Клас tbitmap - глава 10
За формат бітової карти - DIB або DDB - відповідає властивість:
type TBitraapHandleType = (bmDIB, bmDDB);
property HandleType: TBitmapHandleType;
Бажану глибину кольору бітової карти можна дізнатися і перевстановити, змінюючи значення властивості:
TPixelFormat = (pfDevice, pflbit, pf4bit, pfSbit, pflSbit, pf! 6bit, pf24bit, pf32bit, pfCustom);
property PixelFormat: TPixelFormat;
Режим pfDevice відповідає бітової карті DDB. Глибина кольору в 1, 4 і 8 біт на піксель - традиційна і передбачає наявність у зображення палітри. Інші режими дбають про зберігання безпосередніх яркостей точок в кожному з трьох основних кольорів - червоному (R), зелений (G) і синьому (В). Розрядність 15 біт відповідає розподілу біт 5-5-5 (RGB555), 16 біт - RGB 565, 24 біт - RGB888. Режим 32 біт схожий на 24-бітний, але в ньому додатково доданий четвертий канат (альфа-канал), що містить додаткову інформацію про прозорість кожної точки. Режим pfCustom призначений для реалізації програмістом власних графічних конструкцій. У стандартному класі TBitmap установка властивості PixelFormat в режим pfCustom призведе до помилки - тому використовувати його потрібно тільки в написаних вами нащадках TBitmap.
Бітова карта є одним з видів ресурсів. Природно, що клас TBitmap підтримує завантаження з ресурсів програми:
procedure LoadFromResourcelD (Instance: THandle; ResID: Integer);
procedure LoadFromResourceName (Instance: THandle; const ResName: string);
Тут instance - це глобальна змінна модуля System, що зберігає унікальний ідентифікатор запущеної копії додатка (або динамічної бібліотеки).
Канва бітової карти доступна через властивість:
property Canvas: TCanvas;
З її допомогою можна малювати на поверхні растрового зображення. Зверніть увагу, що ніякі інші нащадки TGraphic канви не мають.
Дескриптори бітової карти і її палітри доступні як властивості:
property Handle: HBITMAP;
property Palette: HPALETTE;
Маючи справу з класом TBitmap, враховуйте, що принцип "один об'єкт - один дескриптор" через наявність механізму кешування невірний. Два методу:
function ReleaseHandle: HBITMAP;
function ReleasePalette: HPALETTE;
повертають дескриптори бітової карти й палітри відповідно, а після цього обнуляют дескриптори, т. е. як би "віддають" їх користувачеві.
При будь-якому зовнішньому зверненні до дескриптора бітової карти і будь-якій спробі малювати на її канві поділ однієї картинки декількома об'єктами переривається, і об'єкт отримує власну копію вмісту дескриптора. Для цього є методи:
- procedure Dormant - вивантажує зображення в потік і знищує дескриптори бітової карти й палітри;
- procedure Freeimage - "звільняє" дескриптор бітової карти для подальшого використання і внесення змін. Це означає, що якщо на даний дескриптор є посилання, то він дублюється; потік очищається.
Бітова карта може бути монохромного і кольорового, що визначено властивістю:
property Monochrome: Boolean;
Значення True відповідає монохромного бітової карті. При його зміні відбувається перетворення вмісту до необхідного виду.
За прозорість бітової карти відповідають наступні властивості:
property TransparentColor: TColor;
type TTransparentMode = (tmAuto, tmFixed);
property TransparentMode: TTransparentMode;
Якщо властивість TransparentMode встановлено в режим tmAuto, то за прозорий (фоновий) приймається колір верхнього лівого пікселя. В іншому випадку цей колір береться із властивості Transparentcolor.
Бітова карта може використовуватися в якості маски для інших бітових карт. В цьому випадку вона перетворюється в двобарвне, де в білий колір фарбуються точки фону (див. Властивість Transparentcolor), а в чорний - всі інші. Для підтримки цього режиму служать наступні методи і властивості:
procedure Mask (Transparentcoior: TColor);
property MaskHandle: HBitmap;
function ReleaseMaskHandle: HBitmap;
Нарешті, останнім за рахунком буде розглянуто дуже важлива властивість бітової карти TBitmap. Якщо формат її зберігання - DIB, тобто можливість отримати доступ до даних самої бітової карти:
property ScanLine [Row: Integer]: Pointer;
Це властивість являє собою масив покажчиків на рядки з даними бітової карти. Параметр ROW містить номер рядка. Слід пам'ятати, що в більшості випадків рядки в бітовій карті впорядковані в пам'яті від низу до верху і фактично першою після заголовка зберігається нижній рядок. Код, який повертає значення властивості ScanLine, це враховує; тому не дивуйтеся, якщо з ростом параметра ROW значення властивості зменшується.
Усередині рядка дані впорядковані відповідно до формату (pixelFormat). Для формату pfsbit все просто - кожен байт в рядку відповідає одному пікселю. Для форматів pfisbit і pfiebit пікселу відповідають два байта (в цих 16 бітах упаковані дані про три каналах), pf24bit - три байта (по байту на канал).
Приблизно так може виглядати оброблювач події onMouseMove, що виводить на панель стану інформацію про яскравість в даній точці (мається на увазі, що формат бітової карти - 8 або 24 біти):
procedure TMainForm.ImagelMouseMove (Sender: TObject; Shift: TShiftState;
if not Assigned (Imagel. Picture.Bitmap) then Exit;
do case PixelFormat of
pfSbit: Statusbarl.SimpleText: = Format ( 'x:. y:. b:.', [x, y, pByteArray (ScanLine [у]) ^ [x]]);
pf24bit: Statusbarl.SimpleText: = Format ( 'x:. y:. R:., G:., B:.',
[X, y, pByteArray (ScanLine [y]) л [3 * х], pByteArray (ScanLine [у]) ^ [3 * x + l], pByteArray (ScanLine [у]) ^ [3 * х + 2] ]);
Саме значення властивості ScanLine змінити не можна (воно є тільки для читання). Але можна змінити дані, на які воно вказує. Ось так можна отримати негатив 24-бітної картинки:
Var line. pByteArray;
For i: = 0 to Imagel.Picture.Bitmap.Height - 1 do
For j: = 0 to Imagel.Picture.Bitmap.Width * 3 - 1 do
Line ^ [j]: = 255 - Line ^ [j];
У Delphi можна зіткнутися з "тезкою" даного об'єкту - структурою TBitmap, описаної у файлі WINDOWS.PAS. Оскільки обидві вони відносяться до однієї і тієї ж предметної області, часто виникають колізії, що призводять до помилок. Нагадаємо, щоб відрізнити структури-синоніми, слід використовувати ім'я модуля, в якому вони описані. Тому якщо у вашій програмі є модулі Windows і Graphics, то потрібно описувати і вживайте типи Windows.TBitmap І Graphics.TBitmap.
var CardsDll. THandle;
CardsDll: = LoadLibraryEx ( 'cards.dll', 0, LOAD_LIBRARY__AS_DATAFILE);
Аналогічним чином можна завантажити бітові карти для всієї колоди. При показі карти, залежно від того, відкрита вона або закрита, промальовується один з об'єктів TBitmap:
if Known then // карта відкрита