如何制作 PNG 资源?

发布于 2024-07-29 08:19:19 字数 235 浏览 5 评论 0原文

我有一个表单,上面有一个大的 TImage 作为背景。 问题是,它作为位图直接存储在 DFM 中,大约占用 3 MB。 原始 PNG 文件约为 250K。 我想尝试通过将 PNG 嵌入资源中来减少膨胀,然后让表单在 OnCreate 期间加载它。 现在我可以做到这一点,因为 Delphi 2009 包含 PNG 支持,但我不太知道如何构建包含 PNG 的资源文件。 有人知道这是怎么做到的吗?

I've got a form with a large TImage on it as a background. Problem is, this is stored directly in the DFM as a bitmap, which takes up about 3 MB. The original PNG file is ~250K. I'd like to try to reduce bloat by embedding the PNG in a resource, and then having the form load it during OnCreate. I can do that now that Delphi 2009 includes PNG support, except I don't quite know how to build a resource file with a PNG in it. Anyone know how that's done?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

空城缀染半城烟沙 2024-08-05 08:19:19

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

Example text file (named myres.rc):

MYPNG RCDATA mypng.png

Added to project:

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

Example of loading at runtime:

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;
旧故 2024-08-05 08:19:19

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

For those who use C++ Builder this code works for me :

In the ResourceTest.rc file

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

In the ResourceTest.rh file

#ifndef ResourceTestRH
#define ResourceTestRH

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

#endif

In the ResourceTest.cpp file

#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);
ㄟ。诗瑗 2024-08-05 08:19:19

如果您使用的是 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 组件中即可。

If you're using Delphi 2009, TImage should store your PNG file as a PNG into the DFM file. The DFM will be larger because the binary content of the Picture.Data property of the TImage object is encoded in the DFM as hexadecimal text. But when the DFM is compiled into your EXE, it is compiled into a binary resource. Your image should then take up the same space inside the form's RCDATA resource as storing the PNG in its own RCDATA resource would.

I just tested this by opening one of my own Delphi 2009 DFM files that have a TImage component with a PNG image loaded at design time in a text editor, copying the contents of the Picture.Data property and pasting them into a hex editor. The hex editor shows me that the Picture.Data property stores an actual PNG file prefixed with 10 bytes. The first byte is $09 and the next 9 bytes spell TPngImage. If I delete those 10 bytes and save the file in the hex editor, I get a proper PNG file.

So if you're using Delphi 2009, simply load the PNG image into a TImage component at design time.

逐鹿 2024-08-05 08:19:19

使用 Resource Hacker 时,PNG 图像会添加“PNG”< em>ResType 而不是常见的 RT_RCDATA

TPngImage Class Helper 为这个问题提供了一个简单的解决方案:

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;

When using Resource Hacker, PNG images are added with 'PNG' ResType rather than common RT_RCDATA.

A TPngImage Class Helper gives a simple solution for this issue :

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;

With a simple use:

var
  pngInfo: TPngImage;
begin
  pngInfo := TPngImage.Create;
  try
    pngInfo.LoadFromRHResourceName(HInstance, 'MY_IMAGE.PNG');
    Image1.Picture.Graphic:= pngInfo;
  finally
    pngInfo.Free;
  end;
end;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文