Recent

Author Topic: [SOLVED] Replacing pixel color with custom color  (Read 1161 times)

AsleyCruz

  • Full Member
  • ***
  • Posts: 107
    • Graphic and web designer
[SOLVED] Replacing pixel color with custom color
« on: August 10, 2024, 08:36:56 pm »
Hi there

I would like to replace every pixel color with a custom color
just like the attached image, but keeping the png transparency.

Can you please provide me a code to do this?
Thanks a lot!
« Last Edit: August 14, 2024, 11:20:48 pm by AsleyCruz »
Graphic & web designer

wp

  • Hero Member
  • *****
  • Posts: 12368
Re: Replacing pixel color with custom color
« Reply #1 on: August 10, 2024, 09:26:33 pm »
Untested:
Code: Pascal  [Select][+][-]
  1. uses
  2.   IntfGraphics, FPImage;
  3.  
  4. procedure CreateMask(AImage: TCustomBitmap; AMaskColor: TColor);
  5. var
  6.   img: TLazIntfImage;
  7.   clr, maskClr: TFPColor;
  8.   x, y: Integer;
  9. begin
  10.   maskClr := TColorToFPColor(AMaskColor);
  11.   img :=AImage.CreateIntfImage;
  12.   try
  13.     for y := 0 to img.Height-1 do
  14.       for x :=0 to img.Width-1 do
  15.       begin
  16.         // get pixel color
  17.         clr := img.Colors[x, y];
  18.         // replace pixel RGB by RGB of mask color, but keep Alpha.
  19.         clr.Red := maskClr.Red;
  20.         clr.Green := maskClr.Green;
  21.         clr.Blue := maskClr.Blue;
  22.         // set modified pixel back into image.
  23.         img.Colors[x, y] := clr;
  24.       end;
  25.     AImage.LoadFromIntfImage(img);
  26.   finally
  27.     img.Free;
  28.   end;
  29. end;
   
     

AsleyCruz

  • Full Member
  • ***
  • Posts: 107
    • Graphic and web designer
Re: Replacing pixel color with custom color
« Reply #2 on: August 10, 2024, 09:44:11 pm »
Untested:

Hi wp, it works, but the image was filled completely with clRed.
Now it must detect transparent pixels to ignore them.

See attached image.

Thanks again!
Graphic & web designer

wp

  • Hero Member
  • *****
  • Posts: 12368
Re: Replacing pixel color with custom color
« Reply #3 on: August 10, 2024, 10:05:02 pm »
Does the original image have an alpha channel, i.e., is its PixelFormat pf32bit?
« Last Edit: August 10, 2024, 10:11:53 pm by wp »

AsleyCruz

  • Full Member
  • ***
  • Posts: 107
    • Graphic and web designer
Re: Replacing pixel color with custom color
« Reply #4 on: August 10, 2024, 10:34:37 pm »
Does the original image have an alpha channel, i.e., is its PixelFormat pf32bit?

Yes it has alpha channel. I have some png images with transparency and would like
to fill them with custom solid color.

The attached images is exactly what I want to do. Thanks
Graphic & web designer

paweld

  • Hero Member
  • *****
  • Posts: 1219
Re: Replacing pixel color with custom color
« Reply #5 on: August 10, 2024, 10:56:47 pm »
Here you have an example with manual selection of source colors from the list, just add a loop that will do it automatically: https://forum.lazarus.freepascal.org/index.php/topic,64315.msg488761.html#msg488761
Best regards / Pozdrawiam
paweld

circular

  • Hero Member
  • *****
  • Posts: 4350
    • Personal webpage
Re: Replacing pixel color with custom color
« Reply #6 on: August 11, 2024, 08:46:06 am »
If the alpha channel is not handled correctly, you can use BGRABitmap to make sure it is. The example of paweld use the ReplaceColor method which replace one color at a time. Combining both approaches, applying wp's idea with BGRABitmap, this would be something like:
Code: Pascal  [Select][+][-]
  1. uses
  2.   SysUtils, BGRABitmap, BGRABitmapTypes;
  3.  
  4. var
  5.   bmp: TBGRABitmap;
  6.   x, y: Integer;
  7.   c: TBGRAPixel;
  8.  
  9. begin
  10.   // Load the image
  11.   bmp := TBGRABitmap.Create('input.png');
  12.   try
  13.     // Iterate through each pixel
  14.     for y := 0 to bmp.Height - 1 do
  15.     begin
  16.       for x := 0 to bmp.Width - 1 do
  17.       begin
  18.         // Get the pixel color
  19.         c := bmp.GetPixel(x, y);
  20.        
  21.         // Replace the color with red while keeping the original alpha
  22.         bmp.SetPixel(x, y, BGRA(255, 0, 0, c.alpha));
  23.       end;
  24.     end;
  25.  
  26.     // Save the modified image
  27.     bmp.SaveToFile('output.png');
  28.   finally
  29.     bmp.Free;
  30.   end;
  31. end.
or using direct pixel access
Code: Pascal  [Select][+][-]
  1. uses
  2.   SysUtils, BGRABitmap, BGRABitmapTypes;
  3.  
  4. var
  5.   bmp: TBGRABitmap;
  6.   x, y: Integer;
  7.   pixelPtr: PBGRAPixel;
  8.  
  9. begin
  10.   // Load the image
  11.   bmp := TBGRABitmap.Create('input.png');
  12.   try
  13.     // Iterate through each pixel using direct access
  14.     for y := 0 to bmp.Height - 1 do
  15.     begin
  16.       pixelPtr := bmp.ScanLine[y]; // Get pointer to the start of the scanline
  17.       for x := 0 to bmp.Width - 1 do
  18.       begin
  19.         // Modify the color directly to red, keeping the original alpha
  20.         pixelPtr^.red := 255;
  21.         pixelPtr^.green := 0;
  22.         pixelPtr^.blue := 0;
  23.         // Move to the next pixel
  24.         Inc(pixelPtr);
  25.       end;
  26.     end;
  27.  
  28.     // Save the modified image
  29.     bmp.SaveToFile('output.png');
  30.   finally
  31.     bmp.Free;
  32.   end;
  33. end.

Code generated by BGRABitmap assistant.
Conscience is the debugger of the mind

wp

  • Hero Member
  • *****
  • Posts: 12368
Re: Replacing pixel color with custom color
« Reply #7 on: August 11, 2024, 08:47:22 am »
Does the original image have an alpha channel, i.e., is its PixelFormat pf32bit?

Yes it has alpha channel. I have some png images with transparency and would like
to fill them with custom solid color.
Please post the image that you want to convert (or send me the link to it by PM).

AsleyCruz

  • Full Member
  • ***
  • Posts: 107
    • Graphic and web designer
Re: Replacing pixel color with custom color
« Reply #8 on: August 14, 2024, 11:20:33 pm »
Hi, I did it with the below code.
See attached animated gif.

Thanks to all of you.

Code: Pascal  [Select][+][-]
  1. procedure ReplacePNGColor(aImage: TBGRABitmap; aColor: TColor);
  2. var x, y: Integer;
  3.   aAlpha:word;
  4. begin
  5.   for y := 0 to aImage.Height-1 do begin
  6.     for x :=0 to aImage.Width-1 do begin
  7.       aAlpha:=aImage.Colors[x,y].Alpha;
  8.       if aAlpha > 0 then begin
  9.         aImage.SetPixel(x,y,aColor);
  10.         aImage.AlphaPixel(x,y,aAlpha);
  11.       end;
  12.     end;
  13.   end;
  14. end;
« Last Edit: August 14, 2024, 11:37:22 pm by AsleyCruz »
Graphic & web designer

 

TinyPortal © 2005-2018