title: Delphi, Direct2D, TBitmap and Transparency
body: <p>I'm struggling to be able to draw a <code>TBitmap</code> with transparency onto a <code>TDirect2DCanvas</code> without losing the transparency.</p>
  
  <p>Having created a <code>TBitmap</code> which acts as the back-buffer for my drawing operation as follows:</p>
  
  <pre><code>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);
  </code></pre>
  
  <p>I then need to draw it onto my <code>TDirect2DCanvas</code>, however the following draws the <code>TBitmap</code> but removes all transparency - the background colour is drawn as red whereas if I just draw onto the <code>TForm.Canvas</code> then the background is transparent.</p>
  
  <pre><code>// 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);
  </code></pre>
  
  <p>My understanding now leads me on to <code>ID2D1Bitmap</code> and <code>IWICBitmap</code> interfaces, so, I can attempt to create an <code>ID2D1Bitmap</code> from the <code>TBitmap</code> using the following code (and <em>assuming</em> that the pixel format is copied across):</p>
  
  <pre><code>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);
  </code></pre>
  
  <p>Now that I have an <code>ID2D1Bitmap</code>, the result is still the same - a red background with no transparency. I guess its entirely feasible that the Direct2D side of things uses a different method for transparency but looking at the propertys of the <code>ID2D1Bitmap</code> provides no clues.</p>
  
  <p>My next guess is to go down the <code>IWICBitmap</code> interface.</p>
  
  <p>Ultimately, my question is: is there a more straightforward or obvious thing that I've missed from the above which would allow the transparent <code>TBitmap</code> to be drawn onto the <code>TDirect2DCanvas</code> surface? Or is all this pain necessary in order to maintain the transparency?</p>
  
  <p><strong>Update</strong></p>
  
  <p>Ok, so after doing a bit more digging around, I can now convert the <code>TBitmap</code> to an <code>IWICBitmap</code> and then onto an <code>ID2D1Bitmap</code> however the issue still remains - transparency which is present in the <code>TBitmap</code> is not copied through when rendering to the <code>TDirect2DCanvas</code>.</p>
  
  <pre><code>// 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);
  </code></pre>
  
  <p>And the result is still a non-transparent bitmap.</p>
  
  <p>So the final thing I've looked into is the PixelFormat of the ID2D1RenderTarget which is the underlying render target of the TDirect2DCanvas.</p>
  
  <pre><code>// 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 
  </code></pre>
  
  <p>So I'm guessing that the real issue is to do with the fact that the <code>ID2D1RenderTarget</code> PixelFormat is ignoring the alpha.</p>