Работая с графическими изображениями в среде разработки Delphi, разработчики часто сталкиваются с необходимостью оптимизации использования памяти. Одним из популярных способов является преобразование TBitmap в TPngImage, что, по мнению многих, должно привести к значительному уменьшению объема используемой памяти. Однако на практике результаты могут оказаться не такими впечатляющими.
Проблема использования TBitmap и TPngImage
Рассмотрим ситуацию, когда у нас есть массив из 11 белых TBitmap с разрешением 512x512 пикселей и 32-битной глубиной цвета. Это означает, что каждый элемент массива занимает примерно 1 МБ памяти. Ожидается, что преобразование TBitmap в TPngImage позволит значительно уменьшить размер изображения, так как формат PNG обычно обеспечивает более эффективное сжатие.
var
Bitmaps: TArray<TBitmap>;
Pngs: TArray<TPngImage>;
Streams: TArray<TMemoryStream>;
Png: TPngImage;
I: Integer;
begin
SetLength(Bitmaps, 11);
SetLength(Pngs, 11);
SetLength(Streams, 11);
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 := Low(Pngs) to High(Pngs) do
begin
Pngs[I] := TPngImage.Create;
Pngs[I].Assign(Bitmaps[I]);
Bitmaps[I].Free;
end;
// Дополнительные операции с TPngImage...
end;
Однако, при мониторинге использования памяти с помощью Диспетчера задач, наблюдается, что реальное уменьшение памяти составляет всего 0.824 МБ. Почему это происходит, и каков наиболее быстрый и эффективный способ потерисного сжатия TBitmap в памяти?
Подтвержденный ответ
Исследования показывают, что для уменьшения использования памяти следует сохранять изображения PNG в массиве потоков памяти, что приводит к значительной экономии памяти:
for I := Low(Pngs) to High(Pngs) do
begin
Png := Pngs[I];
Streams[I] := TMemoryStream.Create;
Png.SaveToStream(Streams[I]);
Png.Free;
end;
Альтернативный ответ и дополнительные замечания
Необходимо учитывать, что Диспетчер задач отображает информацию о "Working Set", которая не всегда точно отражает текущее использование памяти приложением. Кроме того, менеджер памяти FastMM4 может не сразу освобождать память после удаления объектов TBitmap, что также может влиять на показания.
Важно также понимать, что TPngImage может хранить пиксели в разложенном виде для быстрой отрисовки, что делает его использование памяти схожим с TBitmap. Сжатие происходит при сохранении в поток, а не при создании TPngImage.
Для более точного измерения использования памяти можно использовать инструменты, такие как FastMM4, которые предоставляют более детальную информацию о состоянии памяти процесса.
Заключение
Преобразование TBitmap в TPngImage не всегда приводит к желаемому уменьшению использования памяти. Для эффективного сжатия изображений следует использовать потоки памяти и сохранять изображения в сжатом виде. Важно также учитывать, что менеджер памяти может не сразу освобождать память, и инструменты, такие как Диспетчер задач, могут не отображать полную картину использования памяти процессом.
о использовании памяти для изображений в Delphi
Контекст вопроса: при работе с графическими изображениями в Delphi преобразование `TBitmap` в `TPngImage` может не всегда приводить к желаемому уменьшению использования памяти, и важно сохранять и
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.