Save image list in Delphi

zhaozj2021-02-11  207

Originally published in Computer World Daily:

http://www.ccw.com.cn/htm/app/aprog/01_6_5_2.asp

Save Image List in Delphi Cai Jian 01-6-5 02:07:11

Recently, when you do a project, you will have a series of images in the TimageList to be saved to the specified file or binary stream in order to perform dynamic recovery when needed. So find the TimageList class related properties, methods, unfortunately, unfortunately, in TimageList, in TimageList, so that Delphi is not provided in TimageList, so other methods must be taken to expand TimageList's feature to meet The actual project needs.

Solution

method one:

Use the API function imagelist_write and imagelist_read. Both need to specify a parameter of type ISTREAM. The former's role is to save the image list of the specified handle to the binary stream of ISTREAM; the latter is a list of originally saved images from the type ISTREAM. List And return the handle pointing to this image list. IStream is an OLE object that declares in delphi is TSTREAMADAPTER = Class (TinterFaceDObject, ISTREAM), which means that TSTREAMADAPTER is an object that inherits the manipulation IStream interface inherited from TinterFaceDObject. The TSTREAMADAPTER object can realize the manipulation of the Delphi internal TSTREAM object to the ISTREAM interface object.

Method Two:

Inheriting a subclass TIMAGELISTEX from TIMAGELIST to implement custom SaveTOFILEX and SaveTreamTreamEx methods. By default, the image saved in TimageList is combined by a normal image and its mask image, so it is necessary to call the GetImages (INDEX: Integer; Image, Mask: Tbitmap) method provided by the Protected TcustomImageList's Protected PROTECTED section to get The bitmap of the index number and its mask bitmap are specified in the image list, which are saved to a custom file or binary stream, and the LoadFromFireEx and LoadFromstreamStreamEx methods are required to recover image collections from custom files or binary streams.

Implementation steps

Customized TimageListex controls have implemented packages of the above two methods in the Public section.

The TimageListex Class source code is as follows:

Unit imagelistex;

Interface

Uses Windows, Sysutils, Classes, Graphics, Controls, CommCtrl, Imglist, Consts

Type

TimageListex = Class (timagelist)

public

Procedure loadFromfile (const filename: string); // Realize API mode Save

Procedure LoadFromstream (Stream: TStream);

Procedure Savetofile (const filename: string);

Procedure Savetostream (Stream: TStream);

Procedure LoadFromFileEx (const filename: string); // Realize custom mode Save

Procedure LoadFromstreamStreamEx (Stream: TSTream);

Procedure SavetofileEx (const filename: string);

Procedure SavetostreamEx (Stream: TStream);

END;

Procedure register; importation

PROCEDURE register;

Begin

RegisterComponents ('ImageListex', [TimageListex]);

END;

{TIMAGELISTEX}

Procedure Timagelistex.LoadFromfile (const filename: string);

VAR

Stream: TSTREAM;

Begin

Stream: = TFileStream.create (filename, fmopenread);

Try

LoadFromstream (stream);

Finally

Stream.free;

END;

END;

Procedure Timagelistex.LoadFromfileEx (const filename: string);

VAR

Stream: TSTREAM;

Begin

Stream: = TFileStream.create (filename, fmopenread);

Try

LoadFromstreamEx (stream);

Finally

Stream.free;

END;

END;

Procedure Timagelistex.LoadFromstream (Stream: TSTREAM);

VAR

SA: TSTREAMADAPTER;

Begin

SA: = TSTREAMADAPTER.CREATE (Stream);

Try

Handle: = imagelist_read (sa); // Point the handle of the current image list points to the handle obtained from the binary stream

IF Handle = 0 THEN

Raise EREADERROR.CREATERES (@simagereadfail);

Finally

Sa.free;

END;

END;

Procedure Timagelistex.LoadFromstreamEx (Stream: TStream);

VAR

Width, Height: Integer;

Bitmap, Mask: Tbitmap

Binstream: TMemoryStream;

Procedure loadImagefromstream (image: tbitmap);

VAR

Count: DWORD;

Begin

Image.Assign (nil);

Stream.readbuffer (count, sizeof (count); // first read the size of the bitmap

Binstream.clear;

Binstream.copyfrom (stream, count); / / Next reading bit map

Binstream.position: = 0; // Flow pointer reset

Image.LoadFromstream (Binstream);

END;

Begin

Stream.readbuffer (Height, Sizeof (HEIGHT));

Stream.readbuffer (Width, Sizeof (Width));

Self.height: = Height;

Self.width: = width; // Restore the image list original height, width

Bitmap: = Tbitmap.create;

Mask: = Tbitmap.create;

Binstream: = TMEMORYSTREAM.CREATE;

Try

While Stream.Position <> stream.size do

Begin

LoadImageFromstream (Bitmap); // Read the chart from the binary stream

LoadImageFromstream (MASK); // Read the mask bitmap from the binary stream

Add (Bitmap, Mask); // combines bitmaps and its mask bitmaps to the image list;

Finally

Bitmap.free;

Mask.free;

Binstream.free;

END;

END;

Procedure Timagelistex.savetofile (const filename: string);

VAR

Stream: TSTREAM;

Begin

Stream: = TfileStream.create (filename, fmcreate);

Try

SaveTostream (stream);

Finally

Stream.free;

END;

END;

Procedure Timagelistex.savetofileEx (Const filename: string);

VAR

Stream: TSTREAM;

Begin

Stream: = TfileStream.create (filename, fmcreate);

Try

SavetostreamEx (stream);

Finally

Stream.free;

END;

END;

Procedure Timagelistex.saveTostream (Stream: TStream);

VAR

SA: TSTREAMADAPTER;

Begin

SA: = TSTREAMADAPTER.CREATE (Stream);

Try

If not imagelist_write (handle, sa) then // save the current image list to the binary stream

Raise EwriteError.createres (@SimageWriteFail);

Finally

Sa.free;

END;

END;

Procedure Timagelistex.saveTroupTreamEx (Stream: TStream);

VAR

I: integer;

Width, Height: Integer;

Bitmap, Mask: Tbitmap

Binstream: TMemoryStream;

Procedure setImage (image: tbitmap; ismask: boolean);

Begin

Image.Assign (NIL); / / Clear the previously saved image to avoid image overlapping

WITH Image Do

Begin

If ismask the monochrome: = true; // Mask Bitmap must use monochrome

Height: = Self.height;

Width: = Self.width;

END;

END;

Procedure SaveImageTroupTream (Image: Tbitmap);

VAR

Count: DWORD;

Begin

Binstream.clear;

Image.savetostream (binstream);

Count: = binstream.size;

Stream.writebuffer (count, sizeof (count); // Save the size of the bitmap first

Stream.copyFrom (binstream, 0); / / then save bitmap

END;

Begin

Height: = Self.height;

Width: = Self.width;

Stream.WriteBuffer (HEIGHT, SIZEOF (HEIGHT)); / / Save the height of the original image list

Stream.WriteBuffer (Width, SizeOf (Width)); / / Save the width of the original image list

Bitmap: = Tbitmap.create;

Mask: = Tbitmap.create;

Binstream: = TMEMORYSTREAM.CREATE;

Try

For i: = 0 to count - 1 do // 一 保 保 保 图像 图像 图像 图像 图像

SetImage (Bitmap, False);

SetImage (Mask, True);

GetImages (I, Bitmap, Mask); // Get the bitmap of the specified index number and its mask bitmap

SaveImageTroupTream (Bitmap); // Save bitmap to the binary stream

SaveImageTroupTream (MASK); // Save Mask Bit map to the binary stream

END;

Finally

Bitmap.free;

Mask.free;

Binstream.free;

END;

END;

End.

The method of use in Delphi is shown below:

First, create a project in Delphi, then place an ImageLisTex control on Form1, a TreeView control, and four Button controls. Associate the image of the TreeView control with ImageListex, any number of images in ImageListex, add a corresponding number of items in the TreeView, the IMAGEX attribute of the item corresponds to the index number of the image in ImageListex. Now you have been able to display the appropriate icons before each project in TreeView.

Finally, write on the Button1 on the onclick event:

Imagelistex1.savetofile ('c: /cj.dat');

ImageListex1.savetofileex ('c: /cjex.dat');

Write on the Button2 onclick event: imagelistex1.clear;

Write on the onclick event of Button3: imagelistex1.loadfromfile ('c: /cj.dat');

Write on the onclick event of Button4: imagelistex1.loadfromfileex ('c: /cjex.dat');

Run the program, first click Button1, then click Button2, and then click Button3 or Button4, you can see that the program can save the image in the image list to the specified file, you can correctly restore and display it from the specified file. .

Conclude

The content introduced in this article has been used to solve the situation I have encountered in the actual project, and I hope that the programmer who will also encounter this problem can find the answer. The above code is tested in Delphi5.0, Windows2000 Server.

转载请注明原文地址:https://www.9cbs.com/read-4415.html

New Post(0)