Recent

Author Topic: SOLVED: Black image on convert a PNG 32bit to 24bit  (Read 2658 times)

AsleyCruz

  • Jr. Member
  • **
  • Posts: 98
    • Graphic and web designer
SOLVED: Black image on convert a PNG 32bit to 24bit
« on: March 27, 2020, 06:46:19 pm »
Hi coders, I would like to convert a PNG image 32bit (with transparency) to 24/16 bits
but the whole image is black. See attached image...

Can you help me please?

Thanks a lot.

Code: Pascal  [Select][+][-]
  1. var
  2.   aPng: TPortableNetworkGraphic;
  3. begin
  4.   aPng := TPortableNetworkGraphic.Create;
  5.   aPng.Assign(Image1.Picture.PNG);
  6.   aPng.PixelFormat := pf24bit;
  7.   aPng.Transparent := True;
  8.   aPng.SaveToFile('zzz.png');
  9. end;
« Last Edit: April 03, 2020, 04:17:39 am by AsleyCruz »
Graphic & web designer

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: Black image on convert a PNG 32bit to 24bit
« Reply #1 on: March 27, 2020, 07:12:27 pm »
Move the aPng.Assign after setting the Pixelformat. In my tests with one of the Lazarus palette images, it is not necessary to set Transparent.

AsleyCruz

  • Jr. Member
  • **
  • Posts: 98
    • Graphic and web designer
Re: Black image on convert a PNG 32bit to 24bit
« Reply #2 on: March 27, 2020, 07:32:09 pm »
Move the aPng.Assign after setting the Pixelformat. In my tests with one of the Lazarus palette images, it is not necessary to set Transparent.

Hi wp
I did the changes but it saves the image ok but in 32bit, not in 24bit.
Any working function that you have used before?

Thanks
Graphic & web designer

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: Black image on convert a PNG 32bit to 24bit
« Reply #3 on: March 27, 2020, 09:52:35 pm »
Sorry, I did not check the PixelFormat... Assign seems to copy the PixelFormat as well. As an alternative you can paint the pf32bit image on the pf24bit canvas of the destination png.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   png: TPortableNetworkGraphic;
  4. begin
  5.   png := TPortableNetworkGraphic.Create;
  6.   try
  7.     png.PixelFormat := pf24bit;
  8.     png.SetSize(Image1.Picture.Width, Image1.Picture.Height);
  9.     png.Canvas.Brush.Color := clWhite;
  10.     png.Canvas.FillRect(0, 0, png.Width, png.Height);
  11.     png.Canvas.Draw(0, 0, Image1.Picture.Png);
  12.     png.SaveToFile('zzz.png');
  13.   finally
  14.     png.Free;
  15.   end;
  16. end;

AsleyCruz

  • Jr. Member
  • **
  • Posts: 98
    • Graphic and web designer
Re: Black image on convert a PNG 32bit to 24bit
« Reply #4 on: March 27, 2020, 11:47:39 pm »
Sorry, I did not check the PixelFormat... Assign seems to copy the PixelFormat as well. As an alternative you can paint the pf32bit image on the pf24bit canvas of the destination png.

Hi wp, the png file does not have transparency and tried to save in pf16bit format
but it is still pf24bit. Anyway, thanks four your time.

Graphic & web designer

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Black image on convert a PNG 32bit to 24bit
« Reply #5 on: March 27, 2020, 11:57:05 pm »
Hi!

You forgot the TransparentColor:

Code: Pascal  [Select][+][-]
  1. aPNG.TransparentColor := clFuchsia;

Winni


winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Black image on convert a PNG 32bit to 24bit
« Reply #6 on: March 28, 2020, 12:30:48 am »
Hi!

No, it was not the TransparentColor.

It was again the roulette with the Canvas.draw.
You'll never know if it's black or white.

I prefer canvas.copyRect:

Code: Pascal  [Select][+][-]
  1. var R : TRect;
  2. ...
  3.  
  4. //png.Canvas.Draw(0, 0, Image1.Picture.Png); // no no no
  5. R := Rect(0,0,Image1.Width, Image1.Height);
  6. Image1.Canvas.CopyRect(R,png.Canvas,R);    
  7.  

Then everything works fine.

Winni

furious programming

  • Hero Member
  • *****
  • Posts: 836
Re: Black image on convert a PNG 32bit to 24bit
« Reply #7 on: March 28, 2020, 01:55:57 am »
@AsleyCruz: IMO you cannot do this with standard classes like TPortableNetworkGraphic. I have a very simillar problem, but I wanted to render the two-colored image and store it as 4bpp windows bitmap. I made it by using TFPMemoryImage — full solution to my problem is in this post of my thread.


If you want to export image to 24bpp PNG, use example from @wp.
« Last Edit: March 28, 2020, 02:11:04 am by furious programming »
Lazarus 3.2 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2026.

lainz

  • Hero Member
  • *****
  • Posts: 4449
    • https://lainz.github.io/
Re: Black image on convert a PNG 32bit to 24bit
« Reply #8 on: March 28, 2020, 01:58:55 am »
Check out LazPaint code, in the save dialog there's an option to save 256 colors and also 24 bit.

furious programming

  • Hero Member
  • *****
  • Posts: 836
Re: Black image on convert a PNG 32bit to 24bit
« Reply #9 on: March 28, 2020, 02:10:37 am »
Fun fact — PNG does not support 16bpp for colored images, so only 24bpp remains.
Lazarus 3.2 with FPC 3.2.2, Windows 10 — all 64-bit

Working solo on an acrade, action/adventure game in retro style (pixelart), programming the engine and shell from scratch, using Free Pascal and SDL. Release planned in 2026.

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Black image on convert a PNG 32bit to 24bit
« Reply #10 on: March 28, 2020, 02:14:12 am »
Hi AsleyCruz

Since I know the BGRA library I dont have to fool around with transparency of bitmap or png which causes often trouble.

Transparency is so easy to handle with BGRA and you dont have to care about 16/24 or 32 bit

One trick in my  example is the use of the "magicWhite" .
It contains the RGB values for white 255/255/255.
But it has an alpha value of zero, so it is complete transparent.
And this value can be changed very simple so the transparent pixels turn tp white.


Code: Pascal  [Select][+][-]
  1. procedure TForm1.SpeedButton1Click(Sender: TObject);
  2. var tmp: TBGRAbitmap;
  3.     magicWhite : TBGRAPixel;
  4. begin
  5.  Image1.Canvas.Brush.color := clYellow;
  6.  Image1.Canvas.FillRect(0,0,Image1.Width, Image1.Height);
  7.  
  8.   MagicWhite :=BGRA(255,255,255,0);
  9.   tmp := TBGRAbitmap.Create (Image1.width,Image1.Height, MagicWhite);
  10.   Tmp.FillEllipseAntialias(100,100,30,30,cssRed);
  11.   tmp.Draw(Image1.Canvas,0,0,false);
  12.   image1.Refresh;
  13.   ShowMessage ('That was transparent'+LineEnding+'Now opaque');
  14.   tmp.AlphaFill(255,0,tmp.NbPixels);
  15.   tmp.Draw(Image1.Canvas,0,0,false);
  16.   image1.Refresh;
  17.   tmp.SaveToFile('Something.png');
  18.   tmp.free;
  19. end;                                    

Winni

 

TinyPortal © 2005-2018