Подтвердить что ты не робот

Как создать ресурс PNG?

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

4b9b3361

Ответ 1

Пример текстового файла (с именем 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;

Ответ 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);

Ответ 3

Если вы используете 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 во время разработки.

Ответ 5

При использовании Resource Hacker изображения в формате PNG добавляются с использованием PNG'ResType вместо обычного RT_RCDATA.

Помощник класса TPngImage предлагает простое решение этой проблемы:

Type
  TPngImageHelper = Class Helper For Vcl.Imaging.pngimage.TPngImage
    Procedure LoadFromRHResourceName(Instance: HInst; Const Name: String);
  End;

...

Procedure TPngImageHelper.LoadFromRHResourceName(Instance: HInst; Const Name: String);
Var
  rs: TResourceStream;
Begin
  rs := TResourceStream.Create(Instance, PChar(Name), 'PNG');
  Try
    LoadFromStream(rs);
  Finally
    rs.Free;
  End;
End;

С помощью простого использования:

var
  pngInfo: TPngImage;
begin
  pngInfo := TPngImage.Create;
  try
    pngInfo.LoadFromRHResourceName(HInstance, 'MY_IMAGE.PNG');
    Image1.Picture.Graphic:= pngInfo;
  finally
    pngInfo.Free;
  end;
end;