The Code Cave

April 20, 2007

Capture an image to a fully paletted bitmap

Filed under: Delphi — Brian @ 4:56 pm

This code does not look like it was mine originally, but I found it in a stray file on my hard drive.  I decided I didn’t want to lose it. 

 It takes a picture of any component you pass in and populates a TBitmap with an image using a custom palette built from device context of the component you are capturing.

DELPHI:
  1.  
  2.  
  3. {******************************************************************************
  4.   ComponentToImg
  5.  ******************************************************************************}
  6. procedure TForm1.ComponentToImg(CHandle: HWND; x: Integer; y: Integer; Width: Integer; Height: Integer; bm: TBitMap);
  7. var
  8.   dc: HDC;
  9.   lpPal : PLOGPALETTE;
  10. begin // ComponentToImg
  11.   // Test width and height
  12.   if ((Width = 0) OR (Height = 0)) then exit;
  13.   bm.Width := Width;
  14.   bm.Height := Height;
  15.  
  16.   // Get the screen dc
  17.   dc := GetDc(CHandle);
  18. try
  19. // If the device doesn’t have a handle, we can’t do anything with it.
  20.   if (dc = 0) then exit;
  21.   // Do we have a palette device?
  22.   if (GetDeviceCaps(dc, RASTERCAPS) AND RC_PALETTE = RC_PALETTE)
  23.   then begin
  24.     // If so, allocate memory for a logical palette
  25.     GetMem(lpPal, sizeof(TLOGPALETTE) + (255 * sizeof(TPALETTEENTRY)));
  26.      try
  27.         // Zero it out to be neat
  28.         FillChar(lpPal^, sizeof(TLOGPALETTE) + (255 * sizeof(TPALETTEENTRY)), #0);
  29.         // Fill in the palette version
  30.         lpPal^.palVersion := $300;
  31.         // Grab the system palette entries
  32.         lpPal^.palNumEntries :=GetSystemPaletteEntries(dc,0,256,lpPal^.palPalEntry);
  33.         // Create the palette
  34.         if (lpPal^.PalNumEntries <> 0) then bm.Palette := CreatePalette(lpPal^);
  35.       finally
  36.         FreeMem(lpPal, sizeof(TLOGPALETTE) + (255 * sizeof(TPALETTEENTRY)));
  37.       end;
  38.   end;
  39.   // Copy from the screen to the bitmap}
  40.   BitBlt(bm.Canvas.Handle, 0, 0, Width, Height, Dc, x, y, SRCCOPY);
  41.  
  42.   // Release the screen dc no matter what happened above.
  43. finally
  44.   ReleaseDc(0, dc);
  45. end
  46. end// ComponentToImg
  47.  
  48. procedure TForm1.Button1Click(Sender: TObject);
  49. begin
  50.   ComponentToImg(self.Handle, 0, 0, 800, 600, Image1.Picture.Bitmap);
  51. end;

3 Comments »

  1. A GetMem and FreeMem without try..finally? brr... Maybe this code could use some tweaking. Otherwise it is a very nice snippet!

    Comment by Walter Heck — April 23, 2007 @ 3:46 am

  2. Good catch! Glad I said it wasn't my code ;)

    Comment by Brian — April 23, 2007 @ 6:57 am

  3. Thanx, Same thing goes for GetDc and ReleaseDC by the way :)

    Comment by Walter Heck — April 23, 2007 @ 7:59 am

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress