Я изо всех сил пытаюсь нарисовать TBitmap
с прозрачностью на TDirect2DCanvas
, не теряя прозрачности.
Создав TBitmap
, который действует как задний буфер для моей операции рисования, следующим образом:
bmp := TBitmap.Create;
bmp.Canvas.Brush.Handle := 0;
bmp.SetSize(100, 100);
bmp.Canvas.Brush.Color := clRed;
bmp.Transparent := true;
bmp.TransparentColor := clRed;
bmp.Canvas.Rectangle(bmp.Canvas.ClipRect);
bmp.Canvas.Pen.Color := clGreen;
bmp.Canvas.Ellipse(bmp.Canvas.ClipRect);
Затем мне нужно нарисовать его на моем TDirect2DCanvas
, однако следующее рисует TBitmap
, но удаляет всю прозрачность - цвет фона рисуется красным, тогда как если я просто рисую на TForm.Canvas
, тогда фон становится прозрачным.
// Drawing onto the TDirect2DCanvas results in a red background
AEventArgs.Canvas.Draw(0, 0, bmp);
// Drawing onto the TForm.Canvas gives the correct result
Self.Canvas.Draw(0, 0, bmp);
Мое понимание теперь приводит меня к интерфейсам ID2D1Bitmap
и IWICBitmap
, поэтому я могу попытаться создать ID2D1Bitmap
из TBitmap
, используя следующий код (и предполагая, что формат пикселей копируется):
var
bmp : TBitmap;
temp : ID2D1Bitmap;
begin
// Code to initialize the TBitmap goes here (from above)
// Create an ID2D1Bitmap from a TBitmap
temp := AEventArgs.Canvas.CreateBitmap(bmp);
// Draw the ID2D1Bitmap onto the TDirect2DCanvas
AEventArgs.Canvas.RenderTarget.DrawBitmap(temp);
Теперь, когда у меня есть ID2D1Bitmap
, результат все тот же — красный фон без прозрачности. Я предполагаю, что вполне возможно, что сторона вещей Direct2D использует другой метод для прозрачности, но просмотр свойств ID2D1Bitmap
не дает никаких подсказок.
Моя следующая догадка — спуститься по интерфейсу IWICBitmap
.
В конечном счете, мой вопрос: есть ли более простая или очевидная вещь, которую я упустил из вышеизложенного, которая позволила бы нарисовать прозрачную TBitmap
на поверхности TDirect2DCanvas
? Или вся эта боль необходима для того, чтобы сохранить прозрачность?
Обновить
Итак, немного покопавшись, я теперь могу преобразовать TBitmap
в IWICBitmap
, а затем в ID2D1Bitmap
, однако проблема все еще остается - прозрачность, присутствующая в TBitmap
, не копируется при рендеринге в TDirect2DCanvas
.
// Create the IWICBitmap from the TBitmap
GetWICFactory.CreateBitmapFromHBITMAP(bmp.Handle, bmp.Palette, WICBitmapUsePremultipliedAlpha, wic);
wic.GetPixelFormat(pif);
// The PixelFormat is correct as `GUID_WICPixelFormat32bppPBGRA` which is
// B8G8R8A8_UNORM and PREMULTIPLIED
// Create the IWICFormatConverter
GetWICFactory.CreateFormatConverter(fc);
fc.Initialize(wic, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nil, 0.0, WICBitmapPaletteTypeCustom);
// Now, create the ID2D1Bitmap
AEventArgs.Canvas.RenderTarget.CreateBitmapFromWicBitmap(fc, nil, temp);
temp.GetPixelFormat(fmt);
// Here, PixelFormat is correct matching the PixelFormat from the IWICBitmap
// Draw the bitmap to the Canvas
AEventArgs.Canvas.RenderTarget.DrawBitmap(temp);
И в результате получается непрозрачное растровое изображение.
Итак, последнее, что я изучил, — это PixelFormat ID2D1RenderTarget, который является базовой целью рендеринга TDirect2DCanvas.
// Create the canvas
fCanvas := TDirect2DCanvas.Create(Self.Handle);
fCanvas.RenderTarget.GetPixelFormat(pf);
// This gives me a PixelFormat of
// B8G8R8A8_UNORM but D2D1_ALPHA_MODE_IGNORE
Итак, я предполагаю, что реальная проблема связана с тем фактом, что ID2D1RenderTarget
PixelFormat игнорирует альфу.
TransparentStretchBlt
в «графике»). - person Sertac Akyuz   schedule 19.07.2016