如何制作PNG资源?

时间:2009-07-20 12:51:02

标签: delphi png delphi-2009 resources

我有一张带有大型TImage的表格作为背景。问题是,它作为位图直接存储在DFM中,占用大约3 MB。原始的PNG文件大约是250K。我想尝试通过在资源中嵌入PNG来减少膨胀,然后在OnCreate期间使用表单加载它。我现在可以这样做,因为Delphi 2009包含PNG支持,除了我不太清楚如何使用PNG构建资源文件。有谁知道这是怎么做的?

5 个答案:

答案 0 :(得分:53)

示例文本文件(名为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;

答案 1 :(得分:2)

对于那些使用C ++ 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);

答案 2 :(得分:1)

如果您使用的是Delphi 2009,TImage应将您的PNG文件作为PNG存储到DFM文件中。 DFM将更大,因为TImage对象的Picture.Data属性的二进制内容在DFM中编码为十六进制文本。但是当DFM被编译到您的EXE中时,它会被编译成二进制资源。然后,您的图像应占用表单的RCDATA资源中的相同空间,因为将PNG存储在其自己的RCDATA资源中。

我刚刚打开了一个我自己的Delphi 2009 DFM文件来测试这个文件,这些文件的TImage组件在设计时在文本编辑器中加载了PNG图像,复制了Picture.Data属性的内容并将它们粘贴到一个十六进制中编辑。十六进制编辑器向我显示Picture.Data属性存储一个前缀为10个字节的实际PNG文件。第一个字节是$ 09,接下来的9个字节拼写为TPngImage。如果我删除这10个字节并将文件保存在十六进制编辑器中,我会得到一个正确的PNG文件。

因此,如果您使用的是Delphi 2009,只需在设计时将PNG图像加载到TImage组件中即可。

答案 3 :(得分:1)

答案 4 :(得分:0)

使用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;