isa
isa

Reputation: 1085

TBitmap to TPngImage and Memory usage

I have an array of 11 white TBitmaps (32-bit 512x512 pixles = 1 MB) and I want to assign them to TPngImage array to reduce memory usage, I expect the 1 mb white bitmap to become 1.76 KB png and the memory usage drop dramatically I monitored that with task manager and the difference is just 0.824 MB why is that? and what is the best/fast way to lossless compress TBitmaps in memory?


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;


Update

Form @bummi research I think the best thing to do is to save the pngs in a memory stream array, that makes the difference 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;

Upvotes: 3

Views: 1789

Answers (2)

Maxim Masiutin
Maxim Masiutin

Reputation: 4812

The TPngImage keep all the pixels ready and unpacked in order to be able to quickly pain them. TPngImage takes about the same amount of memory as TBitmap.

So, simply assigning a bitmap to the TPngImage will just copy the data. Thus, after freeing the bitmap your program will end up using the same amount of memory.

If you expect memory usage to drop to 1.76 KB png, you have to compress the PNG to a memory stream and free the TPngImage, as the code in your update does.

Upvotes: 0

Arioch 'The
Arioch 'The

Reputation: 16065

When you released TBitmap you released two things:

  • memory to FastMM4 Delphi Heap manager
  • HBITMAP Windows GDI Handle

Sometimes Windows would shrink Working Set if you minimize all the program's windows and then restore them back, but it is not granted. Re-arranging process memory due to relatively small today 10MB difference would not be slowing down for nothing.

Read more starting with answer at https://stackoverflow.com/a/14380287/976391

http://fastmm.sourceforge.net/ comes with readme and demo how to measure memory usage inside process, if it makes you curios.

But if you really want to reduce RAM usage - then do not allocate it. Just make one TBitmap and assign al PNGs from it. Though again, your Widows clearly said that 10MB is not the figure to care about.


also, as user539848 spotted, you have 11 bitmaps, not 10. To avoid off-by-one errors you better do not use magical constants but use reliable compiler constructs.

for I := Low(Bitmaps) to High(Bitmaps) do
begin
  Bitmaps[I] :=...

Upvotes: 1

Related Questions