Добавление 32-битного растрового изображения в ImageList
Я пытаюсь создать и нарисовать во время выполнения 32-битное растровое изображение, а затем добавить его в ImageList. Растровое изображение имеет прозрачность (альфа-канал). Я могу без проблем создать растровое изображение и нарисовать его на холсте, и он обычно рисует с прозрачностью поверх любого другого холста.
Проблема в том, что когда я добавляю его в ImageList, изображение теряет рисунки, сделанные с помощью свойства Canvas растрового изображения.
Вот как я запускаю растровое изображение:
Bitmap := TBitmap.Create;
Bitmap.PixelFormat := pf32bit;
Bitmap.Transparent := True;
Bitmap.AlphaFormat := afDefined;
SetBkMode(Bitmap.Canvas.Handle, TRANSPARENT);
Bitmap.SetSize(100, 42);
// now I can draw, let's say, an icon from an imagelist
ImageList.Draw(Bitmap.Canvas, 5, 5, 0, dsTransparent, itImage);
// and some other stuff
Bitmap.Canvas.RoundRect(0, 0, 99, 41, 5, 5);
Bitmap.Canvas.TextOut(50, 5, 'Test string');
Если я рисую это растровое изображение на каком-либо элементе управления, он обычно рисует вместе с изображением из списка изображений, прямоугольником со скругленными углами и текстом с прозрачным фоном (в любом месте, где ничего не было нарисовано, будет прозрачным; будет сохраняться фон, который уже был там), Это означает, что Form1.Canvas.Draw(0, 0, Bitmap);
нарисует растровое изображение поверх Form1, и если там было какое-либо другое изображение, оно будет сохранено в качестве фона.
НО, если я добавлю это растровое изображение в список изображений, возникнет странная проблема. В ImageList для ColorDepth установлено значение cd32bit, а затем я вызываю:
BitmapImageList.Width := Bitmap.Width;
BitmapImageList.Hieght := Bitmap.Height;
BitmapImageList.Add(Bitmap, nil);
Теперь, если я попытаюсь нарисовать это изображение из списка изображений с помощью:
BitmapImageList.Draw(Form1.Canvas, 0, 0, 0);
Единственное, что будет отображаться, это изображение, которое было нарисовано в Bitmap из ImageList, закругленный прямоугольник и текст, нарисованный в Canvas, исчезают.
Что мне не хватает?
1 ответ
Это может быть сделано путем создания дополнительного растрового изображения (Intrans), чей альфа-канал установлен в 0.
Intrans используется для ImageList. Добавьте в качестве изображения исходное растровое изображение в качестве маски.
Пример должен отражать ваш.
type
pRGBQuadArray = ^TRGBQuadArray;
TRGBQuadArray = ARRAY [0 .. 0] OF TRGBQuad;
Procedure GenIntransparentBitmap(bmp, Intrans: TBitmap);
var
pscanLine32: pRGBQuadArray;
i, j: Integer;
begin
Intrans.Assign(bmp);
for i := 0 to Intrans.Height - 1 do
begin
pscanLine32 := Intrans.Scanline[i];
for j := 0 to Intrans.Width - 1 do
begin
pscanLine32[j].rgbReserved := 0;
end;
end;
end;
procedure TForm3.Button1Click(Sender: TObject);
var
Bitmap, Intransp: TBitmap;
begin
Bitmap := TBitmap.Create;
try
Bitmap.PixelFormat := pf32bit;
Bitmap.Transparent := true;
Bitmap.AlphaFormat := afIgnored;
SetBkMode(Bitmap.Canvas.Handle, BKMODE_LAST);
Bitmap.SetSize(100, 42);
ImageList1.Draw(Bitmap.Canvas, 5, 5, 0, dsTransparent, itImage);
Bitmap.Canvas.Brush.Style := bsClear;
Bitmap.Canvas.RoundRect(0, 0, 99, 41, 5, 5);
Bitmap.Canvas.TextOut(50, 5, 'Test string');
BitmapImageList.Width := Bitmap.Width;
BitmapImageList.Height := Bitmap.Height;
// Create intransparent bitmap from transparent bitmap
Intransp := TBitmap.Create;
try
GenIntransparentBitmap(Bitmap, Intransp);
// add intransparent bitmap as image and transparent bitmap as mask
BitmapImageList.Add(Intransp, Bitmap);
finally
Intransp.Free;
end;
BitmapImageList.Draw(Canvas, 100, 100, 0);
finally
Bitmap.Free;
end;
end;
Более короткая версия будет
Procedure GenIntransparentBitmap(bmp, Intrans: TBitmap);
begin
Intrans.Assign(bmp);
Intrans.PixelFormat := pf24bit;
end;
procedure TForm3.Button1Click(Sender: TObject);
var
Bitmap, Intransp: TBitmap;
begin
Bitmap := TBitmap.Create;
try
Bitmap.PixelFormat := pf32bit;
SetBkMode(Bitmap.Canvas.Handle, TRANSPARENT);
Bitmap.SetSize(100, 42);
ImageList1.Draw(Bitmap.Canvas, 5, 5, 0, dsTransparent, itImage);
Bitmap.Canvas.Brush.Style := bsClear;
Bitmap.Canvas.RoundRect(0, 0, 99, 41, 5, 5);
Bitmap.Canvas.TextOut(50, 5, 'Test string');
BitmapImageList.Width := Bitmap.Width;
BitmapImageList.Height := Bitmap.Height;
// Create intransparent bitmap from transparent bitmap
Intransp := TBitmap.Create;
try
GenIntransparentBitmap(Bitmap, Intransp);
// add intransparent bitmap as image and transparent bitmap as mask
BitmapImageList.Add(Intransp, Bitmap);
finally
Intransp.Free;
end;
BitmapImageList.Draw(Canvas, 100, 100, 0);
finally
Bitmap.Free;
end;
end;