Making Bitmap Palette Darker

Hi.
I want to make a bitmap darker.
Lets say R := R div 2, G := G div 2, B := B div 2.

Does anyone have an example of how to get the bitmap palette, change it and put it back.

Thanks in advance.
LVL 1
TheSwineAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
LischkeConnect With a Mentor Commented:
Hi,

here's how to manipulate the palette (not all the bitmap bits):

procedure OffsetPalette(Bitmap: TBitmap; dR, dG, dB: ShortInt);

var
  Pal: TMaxLogPalette;
  I: Integer;

begin
  GetPaletteEntries(Bitmap.Palette, 0, 256, Pal);
  for I := 0 to 255 do
  begin
    Pal.palPalEntry[I].peRed := Pal.palPalEntry[I].peRed + dR;
    Pal.palPalEntry[I].peGreen := Pal.palPalEntry[I].peGreen + dG;
    Pal.palPalEntry[I].peBlue := Pal.palPalEntry[I].peBlue + dB;
  end;
  Pal.palVersion := $300;
  Pal.palNumEntries := 256;
  Bitmap.Palette := CreatePalette(PLogPalette(@Pal)^);
end;

You need to make sure there's no overflow (< 0 or > 255 when applying the differences).

Ciao, Mike
0
 
intheCommented:
Hi
maybe you find something here at the graphics info and links section:

http://www.efg2.com/lab/library/delphi/Default.htm
0
 
ITugayCommented:
Hi TheSwine,

I write a procedure to manipulate with colors in TBitmap.
//
procedure MixScanLine( P : PByteArray; Trans,Len : word; R,G,B : byte);
//
where
   P : PByteArray - pointer to scanline of bitmap
   Trans - (1..99) transparency
   R,G,B - (0..255) colors to mixup, if all of color =0, then Bitmap becam darker, 255 - lighter. How lighter or darker depend from Trans parameter.

You may play with parameters to see what happen. The sample of using this procedure is bellow.

-----------------
procedure TForm1.SpeedButton2Click(Sender: TObject);
var P : PByteArray;
    Y : integer;
begin
   for Y:=0 to Image1.Picture.Bitmap.Height-1 do
   begin
      P:=Image1.Picture.Bitmap.ScanLine[Y];
      MixScanLine(P,40,Image1.Picture.Bitmap.Width-1,128,0,128);
   end;
   Image1.Invalidate;
end;
------------------

procedure MixScanLine( P : PByteArray; Trans,Len : word; R,G,B : byte);
begin
   asm
      push esi
      push edi
      push ebx
      push edx

      mov  esi,P
      mov  edi,esi
      mov  bl,100
      mov  cx,Len
      mov  dx,Trans

    @0:
      lodsb
      mul   dl
      div   bl
      add   al,byte ptr B
      stosb

      lodsb
      mul   dl
      div   bl
      add   al,byte ptr G
      stosb

      lodsb
      mul   dl
      div   bl
      add   al,byte ptr R
      stosb


      dec   cx
      jnz   @0

      pop  edx
      pop  ebx
      pop  edi
      pop  esi
   end;
end;


I hope, you like it.

Cheers,
Igor.
0
 
TheSwineAuthor Commented:
That's works but still there are some problems:
When I load bitmap file to an image component and try this it works, but if I copy the bitmap from other bitmap (Screen e.g.) that doesn't work. when I check the palette value after copying is return 0, is there any way of creating the bitmap i copy to an independable HPalette?

I tried some things but nothing worked so source would be nice.

Here is my source:

procedure TForm2.FormShow(Sender: TObject);
var
  DeskTopDC: HDc;
  DeskTopCanvas: TCanvas;
  DeskTopRect: TRect;
begin

  DeskTopDC := GetWindowDC(GetDeskTopWindow);
  DeskTopCanvas := TCanvas.Create;
  DeskTopCanvas.Handle := DeskTopDC;
  DeskTopRect := Rect(Left, Top, Left+Width, Top + Height);

  Bg.Picture.Bitmap.Width := Width;
  Bg.Picture.Bitmap.Height := Height;
  Bg.Picture.Bitmap.Canvas.CopyRect(Rect(0,0,Width,Height),DeskTopCanvas,DeskTopRect);

  ReleaseDC(GetDeskTopWindow,DeskTopDC);

  Fade;

end;

procedure TForm2.Fade;
var
  Pal: TMaxLogPalette;
  I: Integer;
begin
  if Bg.Picture.Bitmap.Palette = 0 then ShowMessage('Not Good');

  GetPaletteEntries(Bg.Picture.Bitmap.Palette, 0, 256, Pal);
  for I := 0 to 255 do
  begin
    Pal.palPalEntry[I].peRed := Pal.palPalEntry[I].peRed div 3;
    Pal.palPalEntry[I].peGreen := Pal.palPalEntry[I].peGreen div 3;
    Pal.palPalEntry[I].peBlue := Pal.palPalEntry[I].peBlue div 3;
  end;
  Pal.palVersion := $300;
  Pal.palNumEntries := 256;
  Bg.Picture.Bitmap.Palette := CreatePalette(PLogPalette(@Pal)^);
end;

Notes :
*
Form2 is shown whenever I press button on form 1.
*
Bg is TImage component on Form2.
If I load any bitmap into it, The Fade procedure will work.
If it's empty... it's not working.

Thanks in advance.
0
 
LischkeCommented:
You can of course only the palette of images which have actually a palette. Otherwise you need to manipulate the bitmap bits. There is no exception.

You can convert any image to one with palette by decreasing its color depth to at most 8 bit per pixel (set TBitmap.PixelFormat := pf8Bit before you do CopyRect).

Ciao, Mike
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.