转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> Delphi程序 >> 正文
Delphi中保存图像列表         ★★★★

Delphi中保存图像列表

作者:闵涛 文章来源:闵涛的学习笔记 点击数:736 更新时间:2009/4/23 18:41:56

原作发表在计算机世界日报:

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

 

Delphi中保存图像列表


蔡健 01-6-5 下午 02:07:11


最近在做项目时遇到将图像列表(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是从TInterfacedObject继承下来的操纵 IStream接口的对象。通过TStreamAdapter对象可以实现Delphi内部TStream对象对ISTream接口对象的操纵。 方法二: 从TImageList继承一个子类TImageListEx,实现自定义的SaveToFileEx和SaveToStreamEx方法。在默认情况下TImageList中保存的图像是由普通图像及其掩码图像组合而成,所以必须调用其基类TCustomImageList的Protected部分提供的GetImages(Index: Integer; Image, Mask: TBitmap)方法,以获得图像列表中指定索引号的位图及其掩码位图,之后分别保存到自定义的文件或二进制流中,此外还需提供LoadFromFileEx和LoadFromStreamEx方法从自定义的文件或二进制流中恢复图像集合。 实现步骤 自定义的TImageListEx控件在Public部分一并实现了对上述两种方法的封装。 TImageListEx类源代码如下: unit ImageListEx; interface uses Windows, SysUtils, Classes, Graphics, Controls, Commctrl, ImgList, Consts; type TImageListEx = class(TImageList) public procedure LoadFromFile(const FileName: string);//实现API方式保存 procedure LoadFromStream(Stream: TStream); procedure SaveToFile(const FileName: string); procedure SaveToStream(Stream: TStream); procedure LoadFromFileEx(const FileName: string);//实现自定义方式保存 procedure LoadFromStreamEx(Stream: TStream); procedure SaveToFileEx(const FileName: string); procedure SaveToStreamEx(Stream: TStream); end; procedure Register; implementation 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);//将当前图像列表的句柄指向从二进制流中得到的句柄 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));//首先读出位图的大小 BinStream.Clear; BinStream.CopyFrom(Stream, Count);//接着读出位图 BinStream.Position := 0;//流指针复位 Image.LoadFromStream(BinStream); end; begin Stream.ReadBuffer(Height, SizeOf(Height)); Stream.ReadBuffer(Width, SizeOf(Width)); Self.Height := Height; Self.Width := Width;//恢复图像列表原来的高度、宽度 Bitmap := TBitmap.Create; Mask := TBitmap.Create; BinStream := TMemoryStream.Create; try while Stream.Position <> Stream.Size do begin LoadImageFromStream(Bitmap);//从二进制流中读出位图 LoadImageFromStream(Mask);//从二进制流中读出掩码位图 Add(Bitmap, Mask);//将位图及其掩码位图合并添加到图像列表中 end; 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//将当前图像列表保存到二进制流中 raise EWriteError.CreateRes(@SImageWriteFail); finally SA.Free; end; end; procedure TImageListEx.SaveToStreamEx(Stream: TStream); var I: Integer; Width, Height: Integer; Bitmap, Mask: TBitmap; BinStream: TMemoryStream; procedure SetImage(Image: TBitmap; IsMask: Boolean); begin Image.Assign(nil);//清除上一次保存的图像,避免出现图像重叠 with Image do begin if IsMask then Monochrome := True;//掩码位图必须使用单色 Height := Self.Height; Width := Self.Width; end; end; procedure SaveImageToStream(Image: TBitmap); var Count: DWORD; begin BinStream.Clear; Image.SaveToStream(BinStream); Count := BinStream.Size; Stream.WriteBuffer(Count, SizeOf(Count));//首先保存位图的大小 Stream.CopyFrom(BinStream, 0);//接着保存位图 end; begin Height := Self.Height; Width := Self.Width; Stream.WriteBuffer(Height, SizeOf(Height));//保存原图像列表的高度 Stream.WriteBuffer(Width, SizeOf(Width));//保存将原图像列表的宽度 Bitmap := TBitmap.Create; Mask := TBitmap.Create; BinStream := TMemoryStream.Create; try for I := 0 to Count - 1 do//遂一保存图像列表中的图像 begin SetImage(Bitmap, False); SetImage(Mask, True); GetImages(I, Bitmap, Mask);//取得指定索引号的位图及其掩码位图 SaveImageToStream(Bitmap);//保存位图到二进制流中 SaveImageToStream(Mask);//保存掩码位图到二进制流中 end; finally Bitmap.Free; Mask.Free; BinStream.Free; end; end; end. 下面示范在Delphi中的使用方法: 首先在Delphi中新建一个项目,然后在Form1上放置一个ImageListEx控件,一个TreeView控件和四个Button控件。将TreeView控件的Images属性与ImageListEx相关联,在ImageListEx中任意添加几幅图像,在TreeView中添加相应数量的项目,项目的ImageIndex属性分别对应于ImageListEx中图像的索引号。现在TreeView中每个项目之前已经能够显示出相应的图标。 最后,在Button1的OnClick事件中写上: ImageListEx1.SaveToFile(''''C:\CJ.dat''''); ImageListEx1.SaveToFileEx(''''C:\CJEx.dat''''); 在Button2的OnClick事件中写上:ImageListEx1.Clear; 在Button3的OnClick事件中写上:ImageListEx1.LoadFromFile(''''C:\CJ.dat''''); 在Button4的OnClick事件中写上:ImageListEx1.LoadFromFileEx(''''C:\CJEx.dat''''); 运行程序,首先单击Button1,之后单击Button2,最后任意单击Button3或Button4,可以看到程序能够将图像列表中的图像保存到指定的文件中,可以从指定的文件中正确的恢复并显示。 结束语 本文介绍的内容已用于解决本人在实际项目中遇到的情况,也希望同样遇到此问题的程序员能够从中找到答案。以上代码在 Delphi5.0、Windows2000 Server 中调试运行通过。


没有相关教程
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台