デルフィに画像リストを保存
著者:Eve Cole
更新時間:2025-02-03 12:00:04
最近、プロジェクトで作業しているときに、イメージ リスト (TImageList) 内の一連のイメージを指定したファイルまたはバイナリ ストリームに保存して、必要なときに動的に復元できるようにするという状況に遭遇しました。そこで、Delphi のヘルプで TImageList クラスに関連するプロパティとメソッドを探しました。残念ながら、Delphi は TImageList に SaveToFile メソッドと SaveToStream メソッドを提供していませんでした。したがって、TImageList の現在の制限を考慮すると、他のメソッドを採用する必要があります。実際のプロジェクトのニーズを満たすために TImageList の関数を追加します。 |
API 関数 ImageList_Write および ImageList_Read を使用します。どちらも IStream 型のパラメータを指定する必要があります。前者の機能は、指定されたハンドルのイメージ リストを IStream 型のバイナリ ストリームに保存することです。後者の機能は、元々保存されていたイメージ リストを IStream 型のバイナリ ストリームから読み取ることです。 . を返し、この画像リストへのハンドルを返します。 IStream は OLE オブジェクトであり、Delphi での宣言は TStreamAdapter = class(TInterfacedObject, IStream) です。これは、TStreamAdapter が IStream インターフェイスを操作する TInterfacedObject から継承されたオブジェクトであることを意味します。 TStreamAdapter オブジェクトを通じて、Delphi 内部 TStream オブジェクトによる ISTream インターフェイス オブジェクトの操作を実現できます。 |
TImageList からサブクラス TImageListEx を継承し、カスタムの SaveToFileEx メソッドと SaveToStreamEx メソッドを実装します。デフォルトでは、TImageList に保存される画像は通常の画像とそのマスク画像で構成されているため、基本クラス TCustomImageList の PROtected 部分によって提供される GetImages(Index: Integer; Image, Mask: を呼び出す必要があります) TBitmap) メソッドを使用して、イメージ リスト内の指定されたインデックス番号を持つビットマップとそのマスク ビットマップを取得し、それらをそれぞれカスタム ファイルまたはバイナリ ストリームに保存します。さらに、LoadFromFileEx メソッドと LoadFromStreamEx メソッドを提供する必要があります。カスタム ファイルまたはバイナリ ストリームからビットマップを復元します。ストリームからイメージ コレクションを復元します。 |
カスタム TImageListEx コントロールは、上記の 2 つのメソッドを Public 部分にカプセル化します。 |
TImageListEx クラスのソース コードは次のとおりです。 |
Windows、SysUtils、クラス、グラフィックス、コントロール、Commctrl、ImgList、Consts を使用します。 |
TImageListEx = クラス(TImageList) |
プロシージャ LoadFromFile(const FileName: string);// 保存する API メソッドを実装します |
プロシージャ LoadFromStream(Stream: TStream); |
プロシージャ SaveToFile(const FileName: string); |
プロシージャ SaveToStream(Stream: TStream); |
procedure LoadFromFileEx(const FileName: string);//カスタム保存方法を実現 |
プロシージャ LoadFromStreamEx(Stream: TStream); |
プロシージャ SaveToFileEx(const FileName: string); |
プロシージャ SaveToStreamEx(Stream: TStream); |
RegisterComponents('ImageListEx', [TImageListEx]); |
プロシージャ TImageListEx.LoadFromFile(const FileName: string); |
ストリーム := TFileStream.Create(FileName, fmOpenRead); |
プロシージャ TImageListEx.LoadFromFileEx(const FileName: string); |
ストリーム := TFileStream.Create(FileName, fmOpenRead); |
プロシージャ TImageListEx.LoadFromStream(Stream: TStream); |
SA := TStreamAdapter.Create(ストリーム); |
Handle := ImageList_Read(SA); //現在のイメージ リストのハンドルをバイナリ ストリームから取得したハンドルにポイントします。 |
EReadError.CreateRes(@SImageReadFail); を発生させます。 |
プロシージャ TImageListEx.LoadFromStreamEx(Stream: TStream); |
BinStream: TMemoryStream; |
プロシージャ LoadImageFromStream(画像: TBitmap); |
Stream.ReadBuffer(Count, SizeOf(Count));//最初にビットマップのサイズを読み取ります |
BinStream.CopyFrom(Stream, Count);//次にビットマップを読み取ります |
BinStream.Position := 0; //ストリームポインタのリセット |
Image.LoadFromStream(BinStream); |
Stream.ReadBuffer(高さ, SizeOf(高さ)); |
Stream.ReadBuffer(幅, SizeOf(幅)); |
Self.Width := width;//画像リストの元の高さと幅を復元します |
ビットマップ := TBitmap.Create; |
BinStream := TMemoryStream.Create; |
while Stream.Position <> Stream.Size は実行します |
LoadImageFromStream(Bitmap);//バイナリストリームからビットマップを読み取ります |
LoadImageFromStream(Mask);//バイナリ ストリームからマスク ビットマップを読み取ります |
Add(Bitmap, Mask);//ビットマップとそのマスクビットマップをイメージリストに追加します |
プロシージャ TImageListEx.SaveToFile(const FileName: string); |
ストリーム := TFileStream.Create(FileName, fmCreate); |
プロシージャ TImageListEx.SaveToFileEx(const FileName: string); |
ストリーム := TFileStream.Create(FileName, fmCreate); |
プロシージャ TImageListEx.SaveToStream(Stream: TStream); |
SA := TStreamAdapter.Create(ストリーム); |
ImageList_Write(Handle, SA) ではない場合、// 現在のイメージ リストをバイナリ ストリームに保存します |
raise EWriteError.CreateRes(@SImageWriteFail); |
プロシージャ TImageListEx.SaveToStreamEx(Stream: TStream); |
BinStream: TMemoryStream; |
プロシージャ SetImage(画像: TBitmap; IsMask: ブール値); |
Image.Assign(nil);//画像の重なりを避けるために、最後に保存された画像をクリアします |
if IsMask then MonoChrome := True;//マスク ビットマップはモノクロを使用する必要があります |
プロシージャ SaveImageToStream(画像: TBitmap); |
Image.SaveToStream(BinStream); |
Stream.WriteBuffer(Count, SizeOf(Count));//まずビットマップのサイズを保存します |
Stream.CopyFrom(BinStream, 0);//次にビットマップを保存します |
Stream.WriteBuffer(Height, SizeOf(Height));//元の画像リストの高さを保存します |
Stream.WriteBuffer(Width, SizeOf(Width));//元の画像リストの幅を保存します |
ビットマップ := TBitmap.Create; |
BinStream := TMemoryStream.Create; |
for I := 0 to Count - 1 do//画像リストに画像を保存 |
GetImages(I, Bitmap, Mask);//指定されたインデックス番号を持つビットマップとそのマスク ビットマップを取得します |
SaveImageToStream(Bitmap);//ビットマップをバイナリストリームに保存 |
SaveImageToStream(Mask);//マスク ビットマップをバイナリ ストリームに保存します |
以下は、Delphi での使用方法を示しています。 |
まず Delphi で新しいプロジェクトを作成し、次に ImageListEx コントロール、TreeView コントロール、および 4 つの Button コントロールを Form1 に配置します。 TreeView コントロールの Images プロパティを ImageListEx に関連付け、任意の数の画像を ImageListEx に追加し、対応する数の項目を TreeView に追加します。項目の ImageIndex プロパティは、ImageListEx 内の画像のインデックス番号に対応します。対応するアイコンを TreeView の各項目の前に表示できるようになりました。 |
最後に、Button1 の OnClick イベントを記述します。 |
ImageListEx1.SaveToFile('C:CJ.dat'); |
ImageListEx1.SaveToFileEx('C:CJEx.dat'); |
Button2 の OnClick イベントに次のように記述します。 |
Button3 の OnClick イベントに次のように記述します: ImageListEx1.LoadFromFile('C:CJ.dat'); |
Button4 の OnClick イベントに次のように記述します: ImageListEx1.LoadFromFileEx('C:CJEx.dat'); |
プログラムを実行すると、最初に Button1 をクリックし、次に Button2 をクリックし、最後に Button3 または Button4 をクリックします。プログラムが画像リスト内の画像を指定したファイルに保存し、指定したファイルから画像を正しく復元して表示できることがわかります。 。 |
この記事で紹介した内容は、私が実際のプロジェクトで遭遇した状況を解決するために使用されました。また、同じようにこの問題に遭遇したプログラマがそこから答えを見つけられることを願っています。上記のコードはデバッグに合格し、Delphi5.0 および Windows2000 Server で実行されます。 |