请问哪位有图片变换特效的源代码?

pfstudio 2002-08-02 12:45:50
谢谢!
...全文
26 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
lxlsky 2002-08-05
  • 打赏
  • 举报
回复
利用Delphi实现图像的淡入淡出

方法一:
使用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;interfaceuses 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;implementationprocedure 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:\Test.dat');
ImageListEx1.SaveToFileEx('C:\Test1.dat');
在Button2的OnClick事件中写上:ImageListEx1.Clear;
在Button3的OnClick事件中写上:ImageListEx1.LoadFromFile('C:\Test.dat');
在Button4的OnClick事件中写上:ImageListEx1.LoadFromFileEx('C:\Test1.dat');
运行程序,首先单击Button1,之后单击Button2,最后任意单击Button3或Button4,可以看到程序能够将图像列表中的图像保存到指定的文件中,可以从指定的文件中正确的恢复并显示。

结束语
以上代码在 Delphi5.0、Windows2000 Server 中调试运行通过。

8,304

社区成员

发帖
与我相关
我的任务
社区描述
游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧