Recent

Author Topic: TBitmap color "Search and Replace"  (Read 2286 times)

ArminLinder

  • Sr. Member
  • ****
  • Posts: 314
  • Keep it simple.
TBitmap color "Search and Replace"
« on: February 14, 2017, 09:33:01 pm »
Hi all,

is there a fast way to replace a color with a different color in a TBitmap, keeping the alpha value unchanged?

What I have is a bunch ob BitBtn buttons on form, each having the usual  bitmaps for the different button states. Works well. Currently I have drawn glyphs in shades of black and grey, which fits Windows 7. On Windows 10 it looks alien, because Windows 10 uses blue color tones.

The idea is to replace the black shades with blue shades in FormCreate, so I do not have to maintain two different sets of bitmaps.

I found some code samples which look promising, but haven't got the time to do a lengthy trial session tonight, need a quick solution, so a working code snipped for this would be great.

Thnx

Armin.
Lazarus 3.3.2 on Windows 7,10,11, Debian 10.8 "Buster", macOS Catalina, macOS BigSur, VMWare Workstation 15, Raspberry Pi

derek.john.evans

  • Guest
Re: TBitmap color "Search and Replace"
« Reply #1 on: February 14, 2017, 10:51:45 pm »
Unsure of your exact needs but, its easy to iterate the pixels of a bitmap via rawimage.

Here is some code to offset the hue:
Code: Pascal  [Select][+][-]
  1. uses GraphUtil, Math;
  2. procedure BitmapOffsetHue(A: TBitmap; AOffset: integer);
  3. var
  4.   LHue, LLit, LSat: byte;
  5.   LPix, LEnd: PByte;
  6. begin
  7.   Assert(A.PixelFormat = pf32bit);
  8.   A.BeginUpdate;
  9.   try
  10.     LPix := A.RawImage.Data;
  11.     LEnd := LPix + A.RawImage.DataSize - 4;
  12.     while LPix <= LEnd do begin
  13.       RGBtoHLS(LPix[2], LPix[1], LPix[0], LHue, LLit, LSat);
  14.       LHue := EnsureRange(LHue + AOffset, 0, 255);
  15.       HLStoRGB(LHue, LLit, LSat, LPix[2], LPix[1], LPix[0]);
  16.       Inc(LPix, 4);
  17.     end;
  18.   finally
  19.     A.EndUpdate;
  20.   end;
  21. end;
  22.  

If you have grayscale images you can assign a hue and lightness to colorize.
Code: Pascal  [Select][+][-]
  1. procedure BitmapColourize(A: TBitmap);
  2. var
  3.   LHue, LLit, LSat: byte;
  4.   LPix, LEnd: PByte;
  5. begin
  6.   Assert(A.PixelFormat = pf32bit);
  7.   A.BeginUpdate;
  8.   try
  9.     LPix := A.RawImage.Data;
  10.     LEnd := LPix + A.RawImage.DataSize - 4;
  11.     while LPix <= LEnd do begin
  12.       RGBtoHLS(LPix[2], LPix[1], LPix[0], LHue, LLit, LSat);
  13.       LHue := 140;
  14.       LSat := 128;
  15.       HLStoRGB(LHue, LLit, LSat, LPix[2], LPix[1], LPix[0]);
  16.       Inc(LPix, 4);
  17.     end;
  18.   finally
  19.     A.EndUpdate;
  20.   end;
  21. end;
  22.  

Sometimes I like to load up a paint package to test out what color effect im looking for, and then try to code up a duplicate effect.

Edit: Small bug fix. You should subtract the pixel size from LEnd just in case.
« Last Edit: February 14, 2017, 10:55:26 pm by Geepster »

ArminLinder

  • Sr. Member
  • ****
  • Posts: 314
  • Keep it simple.
Re: TBitmap color "Search and Replace"
« Reply #2 on: February 15, 2017, 07:39:41 am »
Hi ...

looks promising. thank you!

Armin.
Lazarus 3.3.2 on Windows 7,10,11, Debian 10.8 "Buster", macOS Catalina, macOS BigSur, VMWare Workstation 15, Raspberry Pi

 

TinyPortal © 2005-2018