Sign in Join

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

Mailing lists / lazarus / 2008-07

Create transparency

7 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

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

Valdas Jankūnas

Hello,

My code loads a PNG image from resource, modifies it, and then paints on canvas:

var
   png: TPortableNetworkGraphic;
   img: TLazIntfImage;
   bmp: TBitmap;
begin
     // load from resource
     png:=TPortableNetworkGraphic.Create;
     png.LoadFromLazarusResource('a_png_image');
     // prepare for modify
     img:=png.CreateIntfImage;
     png.Free;
     // modyfy
     ...... changing colors, setting alpha, ...
     // prepare for draw
     bmp:=TBitmap.Create;
     bmp.LoadFromIntfImage(img);
     img.Free;
     // paint
     ......

If image in resources has no alpha channel (img.HasTransparency returns False in these cases), then in resulting image i get black colour where i set colTransparent (in "modyfy" code block). How to insert alpha channel (or maybe mask, [transparency==mask in recent graphics changes?]) in existing image?

Valdas Jank?nas

Reply by email

Marc Weustink
to Valdas Jankūnas
Valdas Jank?nas wrote 33 lines
Hello, My code loads a PNG image from resource, modifies it, and then paints on canvas: var png: TPortableNetworkGraphic; img: TLazIntfImage; bmp: TBitmap; begin // load from resource png:=TPortableNetworkGraphic.Create; png.LoadFromLazarusResource('a_png_image'); // prepare for modify img:=png.CreateIntfImage; png.Free; // modyfy ...... changing colors, setting alpha, ... // prepare for draw bmp:=TBitmap.Create; bmp.LoadFromIntfImage(img); img.Free; // paint ...... If image in resources has no alpha channel (img.HasTransparency returns False in these cases), then in resulting image i get black colour where i set colTransparent (in "modyfy" code block). How to insert alpha channel (or maybe mask, [transparency==mask in recent graphics changes?]) in existing image?

Before setting alpha values, the Rawimage description used by the IntfImage requires an Alpha channel. When setting full transpacency for a pixel, the value RGBA(0,0,0,0) is used. Without Alpha channel this results in a black pixel.

I don't have a fast (always working) way for adding an alpha channel. A slow way is creating a second image with a rgba description and copy the image.
A faster way, (which might work in most cases) is when you have a 24bit depth description with a 32bits per pixel image. Then you can simply add an alpha description (precision=8, shift=24 or 0) to the rawimage.

Another thing, I'm not sure if loading form IntfImage/RawImage sets the right pixelformat (and thus image description).
Anyway, maybe the bmp is OK. How do you paint it ?

Marc

Reply by email

Valdas Jankūnas
to Marc Weustink

Marc Weustink ra??:

A faster way, (which might work in most cases) is when you have a 24bit depth description with a 32bits per pixel image.

How retrieve image description from TBitmap?

Then you can simply add an alpha description (precision=8, shift=24 or 0) to the rawimage.

How i can do that?

Another thing, I'm not sure if loading form IntfImage/RawImage sets the right pixelformat (and thus image description). Anyway, maybe the bmp is OK. How do you paint it ?

I use Canvas.Draw method.

I found another solution to not use a proxy image, but load resource from stream directly to LazIntfImage (created with Init_BPP32_B8G8R8A8_BIO_TTB description). Now i always got alpha channel and code is flexible to various image types (need just change image reader type). I thing il stay with this solution.

Thanks for help

Valdas Jank?nas

Reply by email

Marc Weustink
to Valdas Jankūnas
Valdas Jank?nas wrote 6 lines
Marc Weustink ra??: > A faster way, (which might work in most cases) is when you have a 24bit > depth description with a 32bits per pixel image. How retrieve image description from TBitmap?

IntfImage.DataDescription

Show quoted text 5 lines
> Then you can simply add > an alpha description (precision=8, shift=24 or 0) to the rawimage. How i can do that?

if Description.BitsPerPixel = 32
then begin
if (Description.RedShift 0)
and (Description.BlueShift 0)
and (Description.GreenShift 0)
then begin

     Description.AlphaPrec := 8;
     Description.AlphaShift := 0;
   end
   else
   if  (Description.RedShift  24)
   and (Description.BlueShift  24)
   and (Description.GreenShift  24)
   then begin
     Description.AlphaPrec := 8;
     Description.AlphaShift := 24;
   end;

end;

Show quoted text 5 lines
> Another thing, I'm not sure if loading form IntfImage/RawImage sets the > right pixelformat (and thus image description). > Anyway, maybe the bmp is OK. How do you paint it ? I use Canvas.Draw method.

Bmp.Canvas.Draw(bitmap) draws in the dept of bmp and not the depth of bitmap. This means if bmp is only created it has pixelformat=pfDevice. Currently that creates a context(and canvas) without alpha channel)

Show quoted text 5 lines
I found another solution to not use a proxy image, but load resource from stream directly to LazIntfImage (created with Init_BPP32_B8G8R8A8_BIO_TTB description). Now i always got alpha channel and code is flexible to various image types (need just change image reader type). I thing il stay with this solution.

Thats ways faster.

Marc

Reply by email

Luiz Americo Pereira Camara
to Valdas Jankūnas: Marc Weustink ra??: How retrieve image description from TBitmap? How i can do that? I use…
Valdas Jank?nas wrote 6 lines
I found another solution to not use a proxy image, but load resource from stream directly to LazIntfImage (created with Init_BPP32_B8G8R8A8_BIO_TTB description). Now i always got alpha channel and code is flexible to various image types (need just change image reader type). I thing il stay with this solution.

Can you provide a code snippet (the loading + how to access the bitmap data )?

I tried that sometime ago without success:
http://thread.gmane.org/gmane.comp.ide.lazarus.general/22010

Luiz

Reply by email

Valdas Jankūnas
to Luiz Americo Pereira Camara

Luiz Americo Pereira Camara ra??:

I tried that sometime ago without success: http://thread.gmane.org/gmane.comp.ide.lazarus.general/22010

I studied Your code and found where problem is: DataDescription need initialize through variable. Working code (seems that TRGBA comes from GraphicEx.pas, but webpage with that source cose is timeouted so i use TRGBAQuad instead):

uses IntfGraphics, LclType, GraphType;

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
procedure DumpMem(Data: PCardinal; Size: Integer);
var
   i: Integer;
   Color: TRGBAQuad;
begin
   for i := 0 to Size - 1 do
   begin
     Color := TRGBAQuad(Data[i]);
     WriteLn('Red: ', Color.Red, ' Green: ', Color.Green,
       ' Blue: ',Color.Blue, ' Alpha: ', Color.Alpha);
   end;
end;
var
   ImgReader: TLazReaderBMP;
   IntfImg: TLazIntfImage;
   aprasas: TRawImageDescription;
begin
   ImgReader := TLazReaderBMP.Create;
   IntfImg := TLazIntfImage.Create(0,0);
   //IntfImg.DataDescription.Init_BPP32_B8G8R8A8_M1_BIO_TTB(0, 0);
   aprasas.Init_BPP32_B8G8R8A8_BIO_TTB(0, 0); // there is
   IntfImg.DataDescription:=aprasas;          // solution
   IntfImg.LoadFromFile('red.bmp', ImgReader);
   DumpMem(PCardinal(IntfImg.PixelData), IntfImg.DataDescription.Height
* IntfImg.DataDescription.Width);
   ImgReader.Destroy;
   IntfImg.Destroy;
end;
Valdas Jank?nas

Reply by email

Valdas Jankūnas
to Marc Weustink: IntfImage.DataDescription if Description.BitsPerPixel = 32 then begin if …

Marc Weustink ra??:

Show quoted text 31 lines
Valdas Jank?nas wrote: > Marc Weustink ra??: > >> A faster way, (which might work in most cases) is when you have a 24bit >> depth description with a 32bits per pixel image. > How retrieve image description from TBitmap? IntfImage.DataDescription >> Then you can simply add >> an alpha description (precision=8, shift=24 or 0) to the rawimage. > How i can do that? if Description.BitsPerPixel = 32 then begin if (Description.RedShift 0) and (Description.BlueShift 0) and (Description.GreenShift 0) then begin Description.AlphaPrec := 8; Description.AlphaShift := 0; end else if (Description.RedShift 24) and (Description.BlueShift 24) and (Description.GreenShift 24) then begin Description.AlphaPrec := 8; Description.AlphaShift := 24; end; end;

Thanks

Valdas Jank?nas

Reply by email