3

我有一个包含 11 个白色 TBitmap(32 位 512x512 像素 = 1 MB)的数组,我想将它们分配给 TPngImage 数组以减少内存使用量,我希望 1 mb 白色位图变为 1.76 KB png,内存使用量急剧下降我用任务管理器监控它,差异只有 0.824 MB,为什么会这样?在内存中无损压缩 TBitmap 的最佳/快速方法是什么?


for I := 0 to 10 do
begin
  Bitmaps[I] := TBitmap.Create;
  Bitmaps[I].PixelFormat := pf32bit;
  Bitmaps[I].Canvas.Pen.Color := clWhite;
  Bitmaps[I].SetSize(512,512);
  Bitmaps[I].Canvas.Rectangle(0,0,512,512);
end;

for I := 0 to 10 do begin Pngs[I] := TPngImage.Create; Pngs[I].Assign(Bitmaps[I]); Bitmaps[I].Free; end;


更新

Form @bummi research 我认为最好的办法是将 pngs 保存在内存流数组中,这样可以产生 9.7 MB 的差异。


for I := 0 to 10 do
begin
  Png :=  TPngImage.Create;
  Png.Assign(Bitmaps[I]);
  Streams[I] := TMemoryStream.Create;
  Png.SaveToStream(Streams[I]);
  Bitmaps[I].Free;
  Png.Free;
end;

4

2 回答 2

1

当您发布 TBitmap 时,您发布了两件事:

  • 内存到 FastMM4 Delphi 堆管理器
  • HBITMAP Windows GDI 句柄

有时,如果您最小化所有程序的窗口然后将它们恢复回来,Windows 会缩小工作集,但这是不被允许的。由于今天相对较小的 10MB 差异而重新安排进程内存不会白白放慢速度。

从https://stackoverflow.com/a/14380287/976391的答案开始阅读更多内容

http://fastmm.sourceforge.net/附带自述文件和演示如何测量进程内的内存使用情况,如果它让你感到好奇。

但是,如果您真的想减少 RAM 使用量,请不要分配它。只需制作一个 TBitmap 并从中分配所有 PNG。不过,您的寡妇们再次明确表示,10MB 不是要关心的数字。


此外,正如 user539848 所发现的,您有 11 个位图,而不是 10 个。为了避免一个错误,您最好不要使用神奇的常量,而是使用可靠的编译器构造。

for I := Low(Bitmaps) to High(Bitmaps) do
begin
  Bitmaps[I] :=...
于 2013-04-25T16:36:46.600 回答
0

TPngImage 使所有像素都准备好并解压,以便能够快速处理它们。TPngImage 占用的内存量与 TBitmap 大致相同。

因此,简单地将位图分配给 TPngImage 将只是复制数据。因此,在释放位图后,您的程序最终将使用相同数量的内存。

如果您希望内存使用量降至 1.76 KB png,则必须将 PNG 压缩到内存流并释放 TPngImage,就像更新中的代码一样。

于 2016-10-29T17:03:52.227 回答