Как мне сделать ресурс PNG?

31

У меня есть форма с большим TImage на ней в качестве фона. Проблема в том, что она хранится непосредственно в DFM в виде растрового изображения, которое занимает около 3 МБ. Оригинальный файл PNG составляет ~ 250K. Я хотел бы попытаться уменьшить раздувание, вставив PNG в ресурс, а затем получив форму загрузки во время OnCreate. Я могу сделать это сейчас, когда Delphi 2009 включает поддержку PNG, за исключением того, что я не совсем знаю, как создать файл ресурсов с PNG в нем. Кто-нибудь знает, как это сделать?

Теги:
resources
delphi-2009
png

4 ответа

51
Лучший ответ

Пример текстового файла (с именем myres.rc):

MYPNG RCDATA mypng.png

Добавлен в проект:

{$R 'myres.res' 'myres.rc'}

Пример загрузки во время выполнения:

uses
  PngImage;

var
  Png: TPngImage;
begin
  Png := TPngImage.Create;
  try
    Png.LoadFromResourceName(HInstance, 'MYPNG');
    Image1.Picture.Graphic := Png; // Image1: TImage on the form
  finally
    Png.Free;
  end;
end;
  • 0
    Действительно ли RCDATA является наиболее конкретным типом ресурса, доступным для этого графического типа? Там нет RT_PNG , например?
  • 2
    Хороший вопрос, Роб. Мой установленный Platform SDK предназначен для Windows Server 2003 R2, и я не смог найти PNG-специфическую константу в WinUser.h. Я не уверен, хотя. Это может быть объявлено где-то еще, возможно, в более поздней версии Platform SDK.
Показать ещё 2 комментария
2

Для тех, кто использует С++ Builder, этот код работает для меня:

В файле ResourceTest.rc

IMG_BMP BITMAP "Ressources\\myimage.bmp";
IMG_PNG RCDATA "Ressources\\myimage.png";

В файле ResourceTest.rh

#ifndef ResourceTestRH
#define ResourceTestRH

#define IMG_BMP "IMG_BMP"
#define IMG_PNG "IMG_PNG"

#endif

В файле ResourceTest.cpp

#include "pngimage.hpp"

// Loading bmp image from resource
Graphics::TBitmap *bmpImage = new Graphics::TBitmap();
bmpImage->LoadFromResourceName((int)HInstance, IMG_BMP);

// Loading png image from resource
TPngImage *pngImage = new TPngImage();
pngImage->LoadFromResourceName((int)HInstance, IMG_PNG);
1
1

Если вы используете Delphi 2009, TImage должен хранить ваш PNG файл в виде PNG в файле DFM. DFM будет больше, потому что двоичный контент свойства Picture.Data объекта TImage закодирован в DFM как шестнадцатеричный текст. Но когда DFM скомпилирован в ваш EXE, он скомпилирован в двоичный ресурс. Затем ваше изображение должно занимать одно и то же пространство внутри ресурса RCDATA, поскольку сохранение PNG в собственном ресурсе RCDATA будет.

Я просто протестировал это, открыв один из моих собственных файлов DFM Delphi 2009, у которых есть компонент TImage с PNG-изображением, загруженным во время разработки в текстовый редактор, копируя содержимое свойства Picture.Data и вставляя их в шестнадцатеричный редактор. Шестигранный редактор показывает мне, что свойство Picture.Data хранит фактический файл PNG с префиксом 10 байтов. Первый байт составляет $09 и следующее 9-байтное заклинание TPngImage. Если я удалю эти 10 байт и сохраню файл в шестнадцатеричном редакторе, я получаю нужный файл PNG.

Итак, если вы используете Delphi 2009, просто загрузите PNG-изображение в компонент TImage во время разработки.

  • 0
    Интересно, а как насчет случая, когда изображение повторно используется в нескольких формах? Delphi достаточно умен, чтобы хранить только одну копию, или он хранит изображение n раз, где n - количество компонентов TImage с этим загруженным изображением? :)
  • 3
    Каждый компонент TImage хранит свое изображение независимо от любых других экземпляров TImage. Таким образом, если вы загружаете одно и то же изображение в n экземпляров TImage, одно и то же изображение сохраняется n раз. Один из способов решить эту проблему - использовать наследование форм. Создайте базовую форму с TImage и загрузите в нее изображение. Затем извлеките все формы, которые должны иметь одинаковое изображение из этой формы. Любые свойства, которые не изменяются в формах-потомках, хранятся только в DFM формы-предка. Это включает в себя данные изображения TImage.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню