Прозрачная растровая кисть
Следующий модуль выводит на форме два изображения. Одно используется в качестве фона, второе выводится на передний план. Изображение переднего плана отображается как изображение, обладающее "прозрачностью".
Более подробную информацию можно почерпнуть из комментариев.
{ Цель: Вывод прозрачного изображения, загруженного из файла Автор: Michael Vincze (vincze@ti.com) Дата: 04/20/95 Использование: Создайте пустую форму с именем Form1, скомпилируйте и запустите проект. Ограничения: Данный модуль протестирован как с 16-, так и с 256-цветными изображениями. Подразумевается, что левый нижний пиксель изображения содержит цвет, определяющий прозрачность. Примечание: Если этот модуль предполагается использовать для любой цели, пожалуйста, оставьте данный заголовок нетронутым в качестве подтверждения авторских прав. Если вы имеете к.-либо замечания или предложения по улучшению кода, пожалуйста, обратитесь к автору. Никаких ограничений по использованию данного кода не существует. Версия: 1.00 04/20/95 Первый выпуск } unit Tbmpu; interface uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } ImageForeGround: TImage; ImageBackGround: TImage; public { Public declarations } end; procedure DrawTransparentBitmap (ahdc: HDC; Image: TImage; xStart, yStart: Word); var Form1: TForm1; implementation {$R *.DFM} procedure DrawTransparentBitmap (ahdc: HDC; Image: TImage; xStart, yStart: Word); var TransparentColor: TColor; cColor : TColorRef; bmAndBack, bmAndObject, bmAndMem, bmSave, bmBackOld, bmObjectOld, bmMemOld, bmSaveOld : HBitmap; hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave : HDC; ptSize : TPoint; begin { устанавливаем цвет прозрачности для левого нижнего пиксела изображения } TransparentColor := Image.Picture.Bitmap.Canvas.Pixels[0, Image.Height - 1]; TransparentColor := TransparentColor or $02000000; hdcTemp := CreateCompatibleDC (ahdc); SelectObject (hdcTemp, Image.Picture.Bitmap.Handle); { выбираем изображение } { преобразуем размеры изображения к логическим точкам } ptSize.x := Image.Width; ptSize.y := Image.Height; DPtoLP (hdcTemp, ptSize, 1); { преобразуем логические точки устройства } { создаем некие DCы для хранения временных данных } hdcBack := CreateCompatibleDC(ahdc); hdcObject := CreateCompatibleDC(ahdc); hdcMem := CreateCompatibleDC(ahdc); hdcSave := CreateCompatibleDC(ahdc); { создаем изображение для каждого DC } { черно-белый DC } bmAndBack := CreateBitmap (ptSize.x, ptSize.y, 1, 1, nil); bmAndObject := CreateBitmap (ptSize.x, ptSize.y, 1, 1, nil); bmAndMem := CreateCompatibleBitmap (ahdc, ptSize.x, ptSize.y); bmSave := CreateCompatibleBitmap (ahdc, ptSize.x, ptSize.y); { каждый DC должен выбрать bitmap-объект для хранения данных о пикселях } bmBackOld := SelectObject (hdcBack, bmAndBack); bmObjectOld := SelectObject (hdcObject, bmAndObject); bmMemOld := SelectObject (hdcMem, bmAndMem); bmSaveOld := SelectObject (hdcSave, bmSave); { устанавливаем соответствующих режим управления (Map) памятью } SetMapMode (hdcTemp, GetMapMode (ahdc)); { сохраняем переданное сюда изображение, поскольку оно будет переписано } BitBlt (hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY); { устанавливаем цвет фона исходного DC в цвет прозрачности (чтобы фон был прозрачным) } cColor := SetBkColor (hdcTemp, TransparentColor); { создаем объект-маску для изображения, выполняя BitBlt(), и делая из исходного изображения черного-белое } BitBlt (hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY); { устанавливаем цвет фона исходного DC обратно в оригинальный цвет } SetBkColor (hdcTemp, cColor); { создаем инвертированную маску-объект } BitBlt (hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, NOTSRCCOPY); { копируем фон главного DC в целевой } BitBlt (hdcMem, 0, 0, ptSize.x, ptSize.y, ahdc, xStart, yStart, SRCCOPY); { маскируем места, где будет располагаться изображение } BitBlt (hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND); { маскируем в изображении пиксели с прозрачным цветом } BitBlt (hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND); { делаем XOR изображения с фоном целевого DC } BitBlt (hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT); { копируем целевое изображение на экран } BitBlt (ahdc, xStart, yStart, ptSize.x, ptSize.y, hdcMem, 0, 0, SRCCOPY); { устанавливаем оригинальное изображение обратно, в переданное сюда изображение } BitBlt (hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY); { удаляем изображения из памяти } DeleteObject (SelectObject (hdcBack, bmBackOld)); DeleteObject (SelectObject (hdcObject, bmObjectOld)); DeleteObject (SelectObject (hdcMem, bmMemOld)); DeleteObject (SelectObject (hdcSave, bmSaveOld)); { удаляем из памяти DCы } DeleteDC (hdcMem); DeleteDC (hdcBack); DeleteDC (hdcObject); DeleteDC (hdcSave); DeleteDC (hdcTemp); end; procedure TForm1.FormCreate(Sender: TObject); begin { создаем для двух изображений элементы управления Image и назначаем им родителей } ImageForeGround := TImage.Create (Form1); ImageForeGround.Parent := Form1; ImageBackGround := TImage.Create (Form1); ImageBackGround.Parent := Form1; { загружаем изображения } ImageBackGround.Picture.LoadFromFile ('c:\delphi\images\splash\16color\earth.bmp'); ImageForeGround.Picture.LoadFromFile ('c:\delphi\images\splash\16color\athena.bmp'); { устанавливаем размер изображения заднего плана равным размеру исходного изображения } with ImageBackGround do begin Left := 0; Top := 0; Width := Picture.Width; Height := Picture.Height; end; { устанавливаем размер изображения переднего плана, отцентрированного по отношению к изображению заднего плана } with ImageForeGround do begin Left := (ImageBackGround.Picture.Width - Picture.Width) div 2; Top := (ImageBackGround.Picture.Height - Picture.Height) div 2; Width := Picture.Width; Height := Picture.Height; end; { не выводим прозрачное изображение так, как это делает BitBlt() функция, пользуемся функцией DrawTransparentBitmap() } ImageForeGround.Visible := False; { рисуем прозрачное изображение обратите внимание на то, как DC переднего плана используется в расположенной ниже функции } DrawTransparentBitmap (ImageBackGround.Picture.Bitmap.Canvas.Handle, {HDC} ImageForeGround, {TImage} ImageForeGround.Left, {X} ImageForeGround.Top {Y} ); end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin { освобождаем изображения } ImageForeGround.Free; ImageBackGround.Free; end; end. |
[001946]