Проблемы и решения: Работа с PNG-изображениями из ресурсов в Delphi 10.1 Berlin
Ответ на задачу пользователя в контексте использования TWICImage в Delphi:
Проблемы и решения: Работа с PNG-изображениями из ресурсов в Delphi 10.1 Berlin
В данной статье рассмотрим проблему, с которой сталкиваются разработчики при работе с PNG-изображениями из ресурсов в среде Delphi 10.1 Berlin. Проблема заключается в том, что функция, предназначенная для загрузки PNG-изображения из ресурсов, не возвращает ожидаемый результат, хотя при этом удается сохранить изображение на диск. Мы подробно разберемся в причинах возникновения данной проблемы и предложим решение, а также рассмотрим альтернативные подходы к работе с изображениями в ресурсах.
Описание проблемы
Разработчик, работающий в среде Delphi 10.1 Berlin, столкнулся с проблемой при попытке изменить изображение на форме, загрузив PNG-изображение из ресурса. Он следовал инструкции по загрузке изображений из встроенных ресурсов и использовал компонент TWICImage для автоматической обработки различных форматов изображений, в том числе PNG для поддержки прозрачности.
Функция LoadImageResource, созданная разработчиком, не возвращала изображение, но при вызове метода SaveToFile внутри функции изображение успешно сохранялось на диск, что подтверждало существование ресурса в исполняемом файле.
function LoadImageResource(NativeInstance: NativeUInt; ImageResource: string): TWICImage;
var
Strm: TResourceStream;
WICImage: TWICImage;
begin
Strm := TResourceStream.Create(NativeInstance, ImageResource, RT_RCDATA);
try
Strm.Position := 0;
WICImage := TWICImage.Create;
try
WICImage.LoadFromStream(Strm);
Result := WICImage; // здесь возвращается пустое значение
Result.SaveToFile('test.png'); // это успешно сохраняет ресурс на диск
finally
WICImage.Free;
end;
finally
Strm.Free;
end;
end;
При попытке присвоения изображения на форме, например, Image1.Picture.Assign(LoadFromResource(...)) или Image1.Picture.Graphic := LoadFromResource(...), изображение не назначалось. Если после этого вызывать Image1.SaveToFile('test.png'), возникала ошибка доступа к неинициализированным данным.
Подтвержденное решение
Проблема заключается в том, что разработчик пытался освободить объект WICImage, который возвращался функцией как результат. В Delphi объекты являются ссылками на экземпляры классов, и после присвоения результата функции, обе ссылки указывают на один и тот же экземпляр. Освобождение объекта приводит к потере ссылки на изображение.
Решение заключается в удалении вызова метода Free для WICImage:
function LoadImageResource(Module: NativeUInt; const ResName: string): TWICImage;
var
Strm: TResourceStream;
begin
Strm := TResourceStream.Create(Module, ResName, RT_RCDATA);
try
Result := TWICImage.Create;
Result.LoadFromStream(Strm);
finally
Strm.Free;
end;
end;
Также стоит добавить обработку исключений для освобождения объекта в случае возникновения ошибки:
function LoadImageResource(Module: NativeUInt; const ResName: string): TWICImage;
var
Strm: TResourceStream;
begin
Strm := TResourceStream.Create(Module, ResName, RT_RCDATA);
try
Result := TWICImage.Create;
try
Result.LoadFromStream(Strm);
except
Result.Free;
raise;
end;
finally
Strm.Free;
end;
end;
Имя функции можно изменить на CreateImageFromResource, чтобы отразить ее предназначение.
Альтернативный ответ
При работе с TPicture необходимо учитывать, что при присвоении TWICImage он создает копию изображения. Поэтому после использования LoadFromResource() необходимо освободить оригинальный TWICImage, возвращаемый функцией:
В качестве альтернативного подхода можно передать TPicture в функцию LoadImageResource(), чтобы она самостоятельно загрузила и присвоила изображение, без необходимости возвращать результат:
procedure LoadImageResource(const APicture: TPicture; Module: NativeUInt; const ResName: string);
var
Strm: TResourceStream;
begin
Strm := TResourceStream.Create(Module, ResName, RT_RCDATA);
try
APicture.Assign(TWICImage.Create);
with APicture.Graphic as TWICImage do
LoadFromStream(Strm);
finally
Strm.Free;
end;
end;
Заключение
В данной статье мы рассмотрели проблему, связанную с загрузкой PNG-изображений из ресурсов в Delphi 10.1 Berlin, и предложили решение, основанное на понимании работы с объектами и ссылками в Delphi. Мы также обсудили альтернативные подходы к работе с изображениями, которые могут помочь избежать ошибок и утечек памяти.
В статье рассматривается проблема, связанная с загрузкой PNG-изображений из ресурсов в среде разработки Delphi 10.1 Berlin, и предложенные решения для устранения возникших трудностей.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.