Нарисуйте растровое изображение, полученное из TPngImageList в GrayScale - PullRequest
0 голосов
/ 07 июня 2018

TImageList позволяет нарисовать одно из его изображений в растровом изображении в отключенном состоянии, используя False в качестве последнего параметра.

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

Я хочу сделать это, а также GrayScale конечное растровое изображение.

У меня есть следующий код:

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;

Проблема в том, что результирующее изображение имеет белый фон.

enter image description here

Как мне сделать фон прозрачным?

Я использую TPngImageList, поскольку он лучше обрабатывает изображения Png, чем обычный TImageList.(в XE4)

1 Ответ

0 голосов
/ 07 июня 2018

Вы можете использовать метод Draw и для TPngImageList.Чтобы получить серое изображение, вы должны сначала включить его в свойстве PngOptions с параметром pngGrayscaleOnDisabled.

...