Stackoverflow delphi question with no answer yet? Can you help?

Stackoverflow delphi question with no answer yet? Can you help?

How do I alpha-blend bitmaps (png or bmp) using only the VCL? Or must I use Win32 APIs like AlphaBlend?  I hear people claiming the VCL has transparency and blending support in the VCL but I don't think they are right.

http://stackoverflow.com/questions/23702868/how-do-you-do-both-blending-and-transparency-using-just-pure-vcl-on-bitmapped-im
http://stackoverflow.com/questions/23702868/how-do-you-do-both-blending-and-transparency-using-just-pure-vcl-on-bitmapped-im

Comments

  1. Use the AlphaBlend API. Here's a copy / paste of some code which uses it. In this case TMouseData hold coordinates of multiple points clicked by the user:

    procedure TMapView.DrawPolygon(xBitmap: TBitmap; xMouse: TMouseData);
    var
      xWidth, xHeight: integer;

      r: TRect;
      p: array of TPoint;
      i: integer;
    begin

      xWidth := xBitmap.Width;
      xHeight := xBitmap.Height;

      fTranslucent.SetSize(xWidth, xHeight);

      r := xBitmap.Canvas.ClipRect;
      fTranslucent.Canvas.CopyMode := SRCCOPY;
      fTranslucent.Canvas.CopyRect(r, xBitmap.Canvas, r);

      SetLength(p, xMouse.ClickCount + 1);
      for i := 0 to xMouse.ClickCount - 1 do
      begin
        p[i].x := xMouse.Click[i].x;
        p[i].y := xMouse.Click[i].y;
      end;

      i := xMouse.ClickCount;
      p[i].x := xMouse.Click[0].x;
      p[i].y := xMouse.Click[0].y;

      fTranslucent.Canvas.Brush.Color := clGray;
      fTranslucent.Canvas.Pen.Style := psClear;
      fTranslucent.Canvas.Polygon(p);

      fBlendFunction.BlendOp := AC_SRC_OVER;
      fBlendFunction.BlendFlags := 0;
      fBlendFunction.SourceConstantAlpha := 80;
      fBlendFunction.AlphaFormat := 0;

      AlphaBlend(xBitmap.Canvas.Handle, 0, 0, xWidth, xHeight, fTranslucent.Canvas.Handle, 0, 0, xWidth, xHeight, fBlendFunction);

      xBitmap.Canvas.Pen.Color := clGray;
      xBitmap.Canvas.Pen.Width := 2;
      xBitmap.Canvas.Pen.Style := psSolid;
      xBitmap.Canvas.Brush.Style := bsClear;

      xBitmap.Canvas.Polyline(p);

    end;

    ReplyDelete
  2. Hi Steve, that's what I suspected I would have to do.  It looks like there's no blending-with-transparency built into the VCL TCanvas itself

    ReplyDelete
  3. Hi Eric,  really my question boils down to "Is Graphics32 or some non-VCL library required, or must I use Win32 API or is something built into VCL?". The answer seems to be "The VCL does not contain any useable transparency/blend functions."

    ReplyDelete
  4. By blending, do you mean the pixel color function is different to the alpha blending function, based on the two other pixel colours?  (Like Photoshop's blend modes?)  In that case, using only the VCL and no third-party libraries, you'll need to do it manually - loop through the pixels and using the two colours [and alpha] compute the resulting colour.

    If you don't mind adding libraries:
    - If you just want alpha transparency, there's https://code.google.com/p/transparent-canvas/ (which I know you're aware of ;) - GDI only, very light-weight, basically a Delphi-ised set of classes that give you a canvas-ish object and use AlphaBlend)
    - If you want Photoshop-like blending modes, use Graphics32.

    ReplyDelete
  5. Steve Maughan AlphaBlend requires pre-multiplied alpha, so your code will render incorrectly when starting from a PNG f.i. (which isn't pre-multiplied).

    Warren Postma Graphics32 will probably be the safer option.

    ReplyDelete
  6. I thought so.  I guess I'll have to look at sucking in Graphics32. I hate adding more libraries to my codebase though. Anyone else feel the pain there? :-)

    ReplyDelete
  7. Warren Postma should be much less painful to your codebase than adding some of the recent EMBT libraries ;-)

    ReplyDelete

Post a Comment