Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Проблемы и решения: Работа с PNG-изображениями из ресурсов в Delphi 10.1 Berlin Ответ на задачу пользователя в контексте использования TWICImage в Delphi:

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, возвращаемый функцией:

Img := LoadFromResource(...);
try
  Image1.Picture.Assign(Img);
finally
  Img.Free;
end;

В качестве альтернативного подхода можно передать 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




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Изображения ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-02-20 22:56:30/0.0024220943450928/0