gpt4 book ai didi

delphi - 不使用 GDI+ 在 Canvas 上绘制 PNG 格式的图片

转载 作者:行者123 更新时间:2023-12-01 22:44:08 25 4
gpt4 key购买 nike

我需要在 Canvas 上绘制 PNG(在 TPicture 中),并满足以下要求:

  1. 它需要非常快(因为目标 PC 运行较慢的 CPU)。
  2. 它不需要任何会增加 exe 大小的额外库(由于目标 PC 通过 2G 移动连接自动更新)。

下面的代码可以完成这项工作,但使用GDI+并且:

  1. 比使用 BitBlt 绘制简单的非透明位图要慢得多。在快速处理器上,绘制时间从 1ms 增加到 16ms。在较慢的 CPU 上,它会从 100 毫秒增加到 900 毫秒。
  2. 将 exe 的大小增加约 0.5MB。

这是 GDI+ 代码。它被设计为在以下情况下回退到标准 BitBlt:

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
ComCtrls, ExtCtrls,

GDIPObj, GDIPAPI;
...

procedure DrawPictureToBitmap(Bitmap: TBitmap; X, Y: Integer; Picture: TPicture);

function PictureToGPBitmap(Picture: TPicture): TGPBitmap;
var
MemStream: TMemoryStream;
begin
MemStream := TMemoryStream.Create;
try
Picture.Graphic.SaveToStream(MemStream);

MemStream.Position := 0;

Result := TGPBitmap.Create(TStreamAdapter.Create(MemStream));
finally
FreeAndNil(MemStream);
end;
end;

var
GDICanvas: TGPGraphics;
GPImage: TGPImage;
begin
GDICanvas := TGPGraphics.Create(Bitmap.Canvas.Handle);
try
GPImage := PictureToGPBitmap(Picture);
try
GDICanvas.DrawImage(GPImage, X, Y);

// Did the draw succeed?
if GDICanvas.GetLastStatus <> Ok then
begin
// No, try a BitBlt!
BitBlt(Bitmap.Canvas.Handle, X, Y, Bitmap.Height, Bitmap.Width, Picture.Bitmap.Canvas.Handle, 0, 0, SRCCOPY);
end;
finally
FreeAndNil(GPImage);
end;
finally
FreeAndNil(GDICanvas);
end;
end;

更新1

根据 David 的建议,我成功地使用 Delphi 内置的 PNG 支持摆脱了 GDI+。

procedure DrawPictureToBitmap(Bitmap: TBitmap; X, Y: Integer; Picture: TPicture);
var
PNG: TPngImage;
MemStream: TMemoryStream;
begin
PNG := TPngImage.Create;
try
MemStream := TMemoryStream.Create;
try
Picture.Graphic.SaveToStream(MemStream);

MemStream.Position := 0;

PNG.LoadFromStream(MemStream);
finally
FreeAndNil(MemStream);
end;

PNG.Draw(Bitmap.Canvas, Rect(X, Y, X + Picture.Width, Y + Picture.Height));
finally
FreeAndNil(PNG);
end;
end;

不幸的是,绘制时间与 GDI+ 方法完全相同。有什么办法可以优化这个吗?

最佳答案

在我看来,您不必要地获取内存中的图形,压缩为 PNG,然后解压缩。可以直接绘制图形。

只需在位图 Canvas 上调用 Draw 并传递 Picture.Graphic:

procedure DrawPictureToBitmap(Bitmap: TBitmap; X, Y: Integer; Picture: TPicture);
begin
Bitmap.Canvas.Draw(X, Y, Picture.Graphic);
end;

此时您可能会认为 DrawPictureToBitmap 毫无意义,将其删除,然后直接调用 Bitmap.Canvas.Draw()

这还有一个令人高兴的好处,即根据问题中的代码,您的图片不限于包含 PNG 图像。

关于delphi - 不使用 GDI+ 在 Canvas 上绘制 PNG 格式的图片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18013011/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com