Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2016-09

Does FCL Image support transparency?

8 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Reimar Grabowski

Hi,

I want to put watermarks on images in a command line application. This doesn't do the trick:

ScaledImage:=TFPCompactImgRGBA8Bit.Create(Width, Height);
Canvas:=TFPImageCanvas.Create(ScaledImage); // TFPImageCanvas
Canvas.StretchDraw(0,0,Width,Height,Image); // Image is TFPCompactImgRGB8Bit
Canvas.Draw(0,0,Watermark); // Watermark is an TFPCompactImgRGBA8Bit

Watermark is a transparent PNG loaded from disk but the transparency is not respected when drawing it onto ScaledImage.

Can FCL Image do this and if not what are my alternatives?

R.

Reply by email

Michael Van Canneyt
to Reimar Grabowski
Reimar Grabowski wrote 13 lines
Hi, I want to put watermarks on images in a command line application. This doesn't do the trick: ScaledImage:=TFPCompactImgRGBA8Bit.Create(Width, Height); Canvas:=TFPImageCanvas.Create(ScaledImage); // TFPImageCanvas Canvas.StretchDraw(0,0,Width,Height,Image); // Image is TFPCompactImgRGB8Bit Canvas.Draw(0,0,Watermark); // Watermark is an TFPCompactImgRGBA8Bit Watermark is a transparent PNG loaded from disk but the transparency is not respected when drawing it onto ScaledImage. Can FCL Image do this and if not what are my alternatives?

It should be able to do this, yes.

Michael.

Reply by email

Mattias Gaertner
to Michael Van Canneyt: It should be able to do this, yes. Michael.
Show quoted text 17 lines
On Fri, 16 Sep 2016, Reimar Grabowski wrote: > Hi, > > I want to put watermarks on images in a command line application. > This doesn't do the trick: > > ScaledImage:=TFPCompactImgRGBA8Bit.Create(Width, Height); > Canvas:=TFPImageCanvas.Create(ScaledImage); // TFPImageCanvas > Canvas.StretchDraw(0,0,Width,Height,Image); // Image is TFPCompactImgRGB8Bit > Canvas.Draw(0,0,Watermark); // Watermark is an TFPCompactImgRGBA8Bit > > Watermark is a transparent PNG loaded from disk but the transparency is not respected when drawing it onto ScaledImage. > > Can FCL Image do this and if not what are my alternatives? It should be able to do this, yes.

TFPCustomCanvas.Draw does not handle Alpha by merging. It simply copies the pixel.
Is this a bug or by design?

Mattias

Reply by email

Michael Van Canneyt
to Mattias Gaertner
Show quoted text 16 lines
>> I want to put watermarks on images in a command line application. >> This doesn't do the trick: >> >> ScaledImage:=TFPCompactImgRGBA8Bit.Create(Width, Height); >> Canvas:=TFPImageCanvas.Create(ScaledImage); // TFPImageCanvas >> Canvas.StretchDraw(0,0,Width,Height,Image); // Image is TFPCompactImgRGB8Bit >> Canvas.Draw(0,0,Watermark); // Watermark is an TFPCompactImgRGBA8Bit >> >> Watermark is a transparent PNG loaded from disk but the transparency is not respected when drawing it onto ScaledImage. >> >> Can FCL Image do this and if not what are my alternatives? > > It should be able to do this, yes. TFPCustomCanvas.Draw does not handle Alpha by merging. It simply copies the pixel. Is this a bug or by design?

I would say it is a bug.

Thinking about it, i would add a parameter to the call to enable this, for efficiency.

Michael.

Reply by email

Reimar Grabowski
to Michael Van Canneyt
I would say it is a bug.

Then StretchDraw is bugged, too.
Or it's no bug at all and TCustomCanvas is just missing alpha blending functionality.

I ended up deriving my own canvas class and implementing the desired functionality there.

R.

Reply by email

Michael Van Canneyt
to Reimar Grabowski
Reimar Grabowski wrote 8 lines
On Fri, 16 Sep 2016 20:31:30 +0200 (CEST) Michael Van Canneyt wrote: > I would say it is a bug. Then StretchDraw is bugged, too. Or it's no bug at all and TCustomCanvas is just missing alpha blending functionality. I ended up deriving my own canvas class and implementing the desired functionality there.

Maybe you can share your code, so we can improve the base class ?

Michael.

Reply by email

Reimar Grabowski
to Michael Van Canneyt
Maybe you can share your code, so we can improve the base class ?

It's just a trivial change to the Draw function and IMO there is little gain implementing it like this for TFPCustomCanvas, but here you go:

-add variables: NewColor, DstColor: TFPColor; alpha: double;
-replace: colors [r,t] := image.colors[xx,t-y] with
begin
  DstColor:=colors[r,t];
  NewColor:=image.colors[xx,t-y];
  alpha:=0;
  if NewColor.alpha>0 then alpha:=NewColor.alpha/65535;
  NewColor.red:=round((NewColor.red*alpha)+DstColor.red*(1-alpha));
  NewColor.green:=round((NewColor.green*alpha)+DstColor.green*(1-alpha));
  NewColor.blue:=round((NewColor.blue*alpha)+DstColor.blue*(1-alpha));
  colors[r,t]:=NewColor;
end;

As you can see this is (SrcColor*ScrAlpha)+DstColor*(1-SrcAlpha) and since I blend RGBA on RGB images there is no need to care about destination alpha. FPCustomCanvas should IMHO allow many different blending equations (think Photoshop/Gimp blending of layers). How about something like:

begin
  if assigned(BlendFunc) then begin
    DstColor:=colors[r,t];
    SrcColor:=image.colors[xx,t-y];
    colors[r,t]:=BlendFunc(SrcColor, DstColor);
  end else
    colors [r,t] := image.colors[xx,t-y];
end;

hih

R.

Reply by email