RaelB
RaelB

Reputation: 3481

Draw a bitmap image that comes from a TPngImageList in GrayScale

TImageList lets you draw one of it's images to a bitmap in a disabled state using False as last parameter.

ImageList.Draw(DestBitmap.Canvas, 0, 0, ImageIndex, False);

I want to do this and also GrayScale the destination bitmap.

I have the following code:

procedure ConvertBitmapToGrayscale(const Bitmap: TBitmap);
type
  PPixelRec = ^TPixelRec;
  TPixelRec = packed record
    B: Byte;
    G: Byte;
    R: Byte;
    Reserved: Byte;
  end;
var
  X: Integer;
  Y: Integer;
  P: PPixelRec;
  Gray: Byte;
begin
  Assert(Bitmap.PixelFormat = pf32Bit);
  for Y := 0 to (Bitmap.Height - 1) do
  begin
    P := Bitmap.ScanLine[Y];
    for X := 0 to (Bitmap.Width - 1) do
    begin
      Gray := Round(0.30 * P.R + 0.59 * P.G + 0.11 * P.B);
      P.R := Gray;
      P.G := Gray;
      P.B := Gray;
      Inc(P);
    end;
  end;
end;

procedure DrawIconShadowPng(ACanvas: TCanvas; const ARect: TRect; ImageList:
    TCustomImageList; ImageIndex: Integer);
var
  ImageWidth, ImageHeight: Integer;
  GrayBitMap : TBitmap;
begin
  ImageWidth := ARect.Right - ARect.Left;
  ImageHeight := ARect.Bottom - ARect.Top;
  with ImageList do
  begin
    if Width < ImageWidth then ImageWidth := Width;
    if Height < ImageHeight then ImageHeight :=  Height;
  end;

  GrayBitMap := TBitmap.Create;
  try
    GrayBitmap.PixelFormat := pf32bit;
    GrayBitMap.SetSize(ImageWidth, ImageHeight);

    ImageList.Draw(GrayBitMap.Canvas, 0, 0, ImageIndex, False);
    ConvertBitmapToGrayscale(GrayBitMap);

    BitBlt(ACanvas.Handle, ARect.Left, ARect.Top, ImageWidth, ImageHeight,
      GrayBitMap.Canvas.Handle, 0, 0, SRCCOPY);
  finally
    GrayBitMap.Free;
  end;
end;

The problem with this is that the resultant image has a white background.

enter image description here

How can I get the background to be transparent?

I am using TPngImageList, since it has better handling of Png images than regular TImageList. (in XE4)

Upvotes: 1

Views: 379

Answers (1)

Uwe Raabe
Uwe Raabe

Reputation: 47704

You can use the Draw method for TPngImageList as well. To get the gray-scaled image you have to enable that in its PngOptions property first with the pngGrayscaleOnDisabled option.

Upvotes: 1

Related Questions