Ich habe Mühe, eine TBitmap
mit Transparenz auf eine TDirect2DCanvas
zu zeichnen, ohne die Transparenz zu verlieren.Delphi, Direct2D, TBitmap und Transparenz
ein TBitmap
erstellt, die für meinen Ziehvorgang als Back-Puffer wirkt wie folgt:
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);
Ich brauche dann auf meine TDirect2DCanvas
zu ziehen, jedoch folgenden die TBitmap
zieht aber entfernt alle Transparenz - die Hintergrundfarbe wird als rot gezeichnet, wohingegen, wenn ich einfach auf die TForm.Canvas
zeichne, der Hintergrund transparent ist.
// 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);
Mein Verständnis jetzt führt mich zu ID2D1Bitmap
und IWICBitmap
Schnittstellen, so kann ich versuchen, ein ID2D1Bitmap
vom TBitmap
mit dem folgenden Code zu erstellen (und unter der Annahme, dass das Pixelformat über kopiert wird):
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);
Nun, da ich ein ID2D1Bitmap
, ist das Ergebnis immer noch der gleiche - ein roter Hintergrund ohne Transparenz. Ich denke, es ist durchaus machbar, dass die Direct2D-Seite der Dinge eine andere Methode für Transparenz verwendet, aber die Eigenschaften der ID2D1Bitmap
bietet keine Hinweise.
Meine nächste Schätzung ist die IWICBitmap
Schnittstelle zu gehen.
Letztendlich ist meine Frage: Gibt es eine einfachere oder offensichtliche Sache, die ich von oben vermisst habe, die die transparente TBitmap
auf die TDirect2DCanvas
Oberfläche gezogen werden könnte? Oder sind all diese Schmerzen notwendig, um die Transparenz zu erhalten?
aktualisieren
Ok, so dass nach ein wenig mehr zu graben um zu tun, kann ich jetzt die TBitmap
auf ein IWICBitmap
konvertieren und dann auf eine ID2D1Bitmap
aber die Frage bleibt - Transparenz, die vorhanden ist in der TBitmap
ist nicht kopiert beim Rendern auf 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);
Und das Ergebnis ist immer noch eine nicht transparente Bitmap.
Also das letzte, was ich untersucht habe, ist das PixelFormat des ID2D1RenderTarget, welches das zugrundeliegende Renderziel des TDirect2DCanvas ist.
// 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
So vermute ich, dass das eigentliche Problem mit der Tatsache zu tun, dass das ID2D1RenderTarget
Pixelformat der Alpha ignoriert.
> * ".. Transparenz, die in der TBitmap vorhanden ist." *> Das ist, was Sie falsch verstanden haben. Diese Bitmap hat keine Transparenz. Es ist die VCL, die es * transparent * mit den Informationen zeichnet, die Sie über die Eigenschaften der TBitmap liefern (siehe 'TransparentStretchBlt' in 'Grafiken'). –