背景として大きなTImage
が付いたフォームがあります。問題は、これがビットマップとしてDFMに直接保存され、約3MBを占めることです。元のPNGファイルは約250Kです。 PNGをリソースに埋め込み、OnCreate
の間にフォームにロードさせることで、膨張を減らしたいと思います。 Delphi 2009にPNGのサポートが含まれているので、これを行うことができます。ただし、PNGを含むリソースファイルを作成する方法がよくわかりません。誰もがそれがどのように行われるか知っていますか?
サンプルテキストファイル(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;
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);
Delphi 2009を使用している場合、TImageはPNGファイルをPNGとしてDFMファイルに保存する必要があります。 TImageオブジェクトのPicture.Dataプロパティのバイナリコンテンツが16進テキストとしてDFMにエンコードされるため、DFMは大きくなります。ただし、DFMがEXEにコンパイルされると、バイナリリソースにコンパイルされます。画像は、フォームのRCDATAリソース内で、PNGを独自のRCDATAリソースに格納するのと同じスペースを占める必要があります。
これをテストしたのは、デザイン時にPNG画像が読み込まれたTImageコンポーネントを含む独自のDelphi 2009 DFMファイルの1つをテキストエディターで開き、Picture.Dataプロパティの内容をコピーして、16進エディターに貼り付けることです。 16進エディタは、Picture.Dataプロパティが10バイトのプレフィックスが付いた実際のPNGファイルを格納していることを示しています。最初のバイトは$ 09で、次の9バイトはTPngImageを綴ります。これらの10バイトを削除し、16進エディターでファイルを保存すると、適切なPNGファイルが得られます。
したがって、Delphi 2009を使用している場合は、設計時にPNG画像をTImageコンポーネントにロードするだけです。
Resource Hacker を使用する場合、PNG画像は '[〜#〜] png [〜#〜]'一般的ではなくResTypeRT_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;