Recent

Author Topic: FCL-Image and Alpha [resolved]  (Read 22954 times)

daz

  • Full Member
  • ***
  • Posts: 112
    • http://matt-shaffer.com
FCL-Image and Alpha [resolved]
« on: May 31, 2010, 10:06:09 am »
I'm wondering if fcl-image has support for the alpha layer of PNGs (or any image format, really). I have a need to create a transparent memory image, then being able to draw to it with partially transparent images.

I made a quick test project, and it seems that fcl-image doesn't support the alpha, at least by default:
Code: [Select]
procedure TForm1.Button1Click(Sender: TObject);
var
   canv: TFPimagecanvas;
   ima,td: TFPmemoryimage;
   writ: TFPcustomimagewriter;
begin
     try
        ima := TFPmemoryImage.Create(200,200);
        ima.UsePalette := false;
        ima.LoadFromFile('in2.png');
        ima.UsePalette := false;
        td := TFPmemoryImage.Create(100,100);
        td.LoadFromFile('in1.png');
        canv := tfpimagecanvas.create(ima);
        canv.Draw(0,0,td);

        writ := tfpwriterpng.create;
        ima.savetofile('test.png', writ);
     finally
            ima.Free;
            td.free;
            canv.Free;
            writ.Free;
     end;
end;
in2.png is a 200x200 fully transparent image. in1.png is a 100x100 black image. Upon drawing in1 on top of in2 and saving it as test.png, the image is fully black, meaning the alpha was not kept upon drawing or saving.

In a somewhat related problem, how can I save PNGs without having them automatically indexed? I tried setting the property UsePalette twice, but it still saves it as indexed.
« Last Edit: June 01, 2010, 02:04:16 pm by daz »

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1927
Re: FCL-Image and Alpha
« Reply #1 on: May 31, 2010, 12:16:56 pm »
Do you mean something like the attached image?
It was made from the Dragon.png here:
http://bugs.freepascal.org/view.php?id=13266

I don't know how it works using fpimage, but I can show you how it works with my own libs.

daz

  • Full Member
  • ***
  • Posts: 112
    • http://matt-shaffer.com
Re: FCL-Image and Alpha
« Reply #2 on: May 31, 2010, 01:56:59 pm »
Yes, like your dragon image. I'd like to have it output transparency like that, but it ends up with a black background like your unrelated bug report's second screenshot.

Chronos

  • Full Member
  • ***
  • Posts: 241
    • PascalClassLibrary
Re: FCL-Image and Alpha
« Reply #3 on: May 31, 2010, 11:51:28 pm »
You should use AggPas which is located in lazarus directory in components subdirectory. Look at components/aggpas/lazarus/examples for demo. LCL don't have complete support for alpha channel. I achieved with merging PNG images with alpha channel using aggpas library recently.

daz

  • Full Member
  • ***
  • Posts: 112
    • http://matt-shaffer.com
Re: FCL-Image and Alpha
« Reply #4 on: June 01, 2010, 12:53:37 am »
You should use AggPas which is located in lazarus directory in components subdirectory. Look at components/aggpas/lazarus/examples for demo. LCL don't have complete support for alpha channel. I achieved with merging PNG images with alpha channel using aggpas library recently.
Would you be so kind as to provide a simple demo yourself? I tried
Code: [Select]
Aggc:=TAggLCLCanvas.Create;
with Aggc do begin
       Image.PixelFormat:=afpimRGBA32;
       Image.SetSize(250,250);
end;
aggc.Draw(0,0,td);
aggc.Image.SaveToFile('test2.png');
where td is my black square from in1.png.

The above code seems to not only fail at saving an alpha layer, but it also doesn't even save the file properly...

Chronos

  • Full Member
  • ***
  • Posts: 241
    • PascalClassLibrary
Re: FCL-Image and Alpha
« Reply #5 on: June 01, 2010, 03:23:57 am »
Actually I realized that I done image manipulation using http://wiki.lazarus.freepascal.org/BGRABitmap instead of AggPas which is in fact vector library.

Then code could look like:
Code: [Select]
uses ..., Graphics, BGRABitmapTypes, BGRABitmap;

procedure MergeImages(FirstFileName, SecondFileName, CombinedFileName: string);
var
  First: TBGRABitmap;
  Second: TBGRABitmap;
begin
  Second := TBGRABitmap.Create(SecondFileName);
  First := TBGRABitmap.Create(FirstFileName);
  First.Bitmap.Canvas.CopyRect(
    Rect(0, 0, First.Width, First.Height),
    Second.Bitmap.Canvas,
    Rect(0, 0, Second.Width, Second.Height)
  );
  First.SaveToFile(CombinedFileName);
  First.Destroy;
  Second.Destroy;
end;

MergeImages('First.png', 'Second.png', 'Combined.png');

TBGRABitmap behave like classic Bitmap with Canvas so there shouldn't be problem to draw into it.
« Last Edit: June 01, 2010, 05:45:19 am by chronos »

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1927
Re: FCL-Image and Alpha
« Reply #6 on: June 01, 2010, 03:50:31 am »
The combined dragon image above was made using my own library:
http://www.theo.ch/lazarus/opbitmap64.zip Register opbitmapforlazcompat.lpk

The code to produce this looks like:

Code: [Select]
uses opbitmap,opbitmapformats;
...
procedure TForm1.Button1Click(Sender:TObject);
var pic1,pic2:TOPPicture;
begin
  pic2:=TOPPicture.Create;
  pic1:=TOPPicture.Create;

  pic1.LoadFromFile('/home/theo/Documents/vd/Dragon.png');
  pic2.Bitmap.Width:=2*pic1.Bitmap.Width;
  pic2.Bitmap.Height:=pic1.Bitmap.Height;

  pic2.Bitmap.Canvas.Brush.color:=clwhite;
  pic2.Bitmap.Canvas.FillRect(Rect(0,0,pic2.Bitmap.Width,pic2.Bitmap.Height));

  pic2.Bitmap.SetAlpha(0); //Make BG full alpha transparent

  pic2.Bitmap.Canvas.Draw(0,0,pic1.Bitmap);
  pic2.Bitmap.Canvas.Draw(pic1.Bitmap.width,0,pic1.Bitmap);

  pic2.SaveToFile('/home/theo/alphaop.png');

  pic2.free;
  pic1.free;
end;

Gintas

  • Jr. Member
  • **
  • Posts: 71
    • Developer's Diary
Re: FCL-Image and Alpha
« Reply #7 on: June 01, 2010, 10:19:48 am »
TBGRABitmap doesn't work for me on Ubuntu 10.04 with FPC 2.5.1 :

Quote
bgragtkbitmap.pas(41,17) Error: There is no method in an ancestor class to be overridden: "TBGRAGtkBitmap.Draw(TCanvas,LongInt,LongInt,Boolean="TRUE");"
bgragtkbitmap.pas(42,17) Error: There is no method in an ancestor class to be overridden: "TBGRAGtkBitmap.Draw(TCanvas,TRect,Boolean="TRUE");"
bgragtkbitmap.pas(48,1) Fatal: There were 2 errors compiling module, stopping

There should some way to save transparent PNGs with AGG. :)

daz

  • Full Member
  • ***
  • Posts: 112
    • http://matt-shaffer.com
Re: FCL-Image and Alpha
« Reply #8 on: June 01, 2010, 10:22:35 am »
Gintas: Would you mind checking to see if Theo's works on Ubuntu? I'm about to test it on Windows.

Chronos' idea for BGRABitmap worked for me on Windows, but cross platform across at least Windows and Linux is a very strong desire.

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1927
Re: FCL-Image and Alpha
« Reply #9 on: June 01, 2010, 10:31:26 am »
Gintas: Would you mind checking to see if Theo's works on Ubuntu? I'm about to test it on Windows.

I made this image on OpenSuSE Linux, so it has to work on Ubuntu.
The code used here does not need X or widgetsets.

daz

  • Full Member
  • ***
  • Posts: 112
    • http://matt-shaffer.com
Re: FCL-Image and Alpha
« Reply #10 on: June 01, 2010, 10:50:50 am »
Gintas: Would you mind checking to see if Theo's works on Ubuntu? I'm about to test it on Windows.

I made this image on OpenSuSE Linux, so it has to work on Ubuntu.
The code used here does not need X or widgetsets.
That's good to know. I got it to work flawlessly on Windows, at least. Only thing I noticed was that in the Readme (I believe) you noted it had Intel asm, so I'm guessing it wouldn't play too nicely with AMD ;) Either way, I suppose that's fine. I don't have a cross compiler set up to compile for a different CPU, nor do I have a computer with an AMD proc.

The only question left on my mind, Theo, is if it's possible to save the PNG's as unindexed. I would think that might be more of a writer-specific thing, but perhaps you have a method to interact with saving palettes.
Apparently the writer is smart enough to know when to index and when not to? Either way, all seems fine and dandy after further testing! Thanks for creating this package theo.
« Last Edit: June 01, 2010, 11:20:43 am by daz »

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1927
Re: FCL-Image and Alpha
« Reply #11 on: June 01, 2010, 11:18:23 am »
That's good to know. I got it to work flawlessly on Windows, at least. Only thing I noticed was that in the Readme (I believe) you noted it had Intel asm, so I'm guessing it wouldn't play too nicely with AMD ;) Either way, I suppose that's fine. I don't have a cross compiler set up to compile for a different CPU, nor do I have a computer with an AMD proc.

The files in the package opbitmapforlazcompat.lpk do not contain asm.
In opbitmapforlaz.lpk, there are some more image format readers which contain asm.
If you only use opbitmapforlazcompat, it should work everywhere.

daz

  • Full Member
  • ***
  • Posts: 112
    • http://matt-shaffer.com
Re: FCL-Image and Alpha [resolved]
« Reply #12 on: June 01, 2010, 07:37:18 pm »
Theo, I'm not sure I quite understand how to have this work the way I'd like it to. (I can create a test project if you'd like)

Code: [Select]
procedure TForm1.Button1Click(Sender: TObject);
var
   p1,p2: TOPPicture;
begin
     p1 := TOPPicture.Create;
     p2 := TOPPicture.Create;
     p1.LoadFromFile('test.png');
     p2.LoadFromFile('test2.png');
     p1.Bitmap.Canvas.Draw(0,0,p2.Bitmap);
     p1.SaveToFile('result1.png');
     p1.Free;
     p2.Free;
end;
I would expect that code to draw p2 on top of p1, but instead, it seems to clear p1 when drawing p2.

[p1 and p2 are both the same size, p1 being a solid color and p2 having some alpha]

EDIT:
After a quick test, it seems that yes, Draw() overwrites p1's data with p2, rather than layering as desired... I can still post up an example if you'd like one.
« Last Edit: June 01, 2010, 08:11:41 pm by daz »

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1927
Re: FCL-Image and Alpha [resolved]
« Reply #13 on: June 02, 2010, 02:54:56 am »
After a quick test, it seems that yes, Draw() overwrites p1's data with p2, rather than layering as desired... I can still post up an example if you'd like one.

Yes, because normal Drawing and AlphaBlending are different codes.
Tell it to use AlphaBlend:

Code: [Select]
procedure TForm1.Button1Click(Sender: TObject);
var
   p1,p2: TOPPicture;
begin
     p1 := TOPPicture.Create;
     p2 := TOPPicture.Create;
     p1.LoadFromFile('test.png');
     p2.LoadFromFile('test2.png');

     p1.Bitmap.PixelFormat:=pf32bit; //make sure
     p2.Bitmap.PixelFormat:=pf32bit; //make sure
     p2.Bitmap.AlphaBlend:=true;

     p1.Bitmap.Canvas.Draw(0,0,p2.Bitmap);
     p1.SaveToFile('result1.png');
     p1.Free;
     p2.Free;
end;
                                 

You can also set the opacity of the entire image to a certain value:

pic.Bitmap.SetAlpha(100); //  0..255 (or consts AlphaTransparent or AlphaOpaque)

daz

  • Full Member
  • ***
  • Posts: 112
    • http://matt-shaffer.com
Re: FCL-Image and Alpha [resolved]
« Reply #14 on: June 02, 2010, 10:20:15 am »
Well, that works to some extent. It just seems to blend differently than I would expect, heh.
This+this=that

expected
This+this=this type of blending

[I think images are disabled]

So I guess I expected overlaying instead of actual blending.

 

TinyPortal © 2005-2018