查看: 96|回复: 1

[教程] TImage组件实现保存图片到Stream

[复制链接]

0

主题

0

回帖

0

积分

积极分子

金币
0
阅读权限
220
精华
0
威望
0
贡献
0
在线时间
0 小时
注册时间
2008-11-11
发表于 2016-5-3 08:54:10 | 显示全部楼层 |阅读模式

因为一个项目,不得不将图片保存到数据库中,需要的时候再从数据库中读取.初时,以为很简单,不就是一个Stream.事实上,也很简单.度娘一下,代码也很多,但,都是坑!

看一下TImage的源,Picture.Graphic下有一个loadfromStream和SavetoStream.如果没有猜错,那么直接用这两个函数就可以了.于是,我做了一个demo测试

demo里放了两个TImage.TImage1放一张图片,然后用代码将TImage1的图片保存到Stream.TImage2再从这个Stream中取出图片.自然水到渠成.

这就是我的代码.

 PicStream:=TMemoryStream.Create;
 Self.Image1.Picture.Graphic.SaveToStream(PicStream);
 PicStream.Position:=0;
 Self.Image2.Picture.Graphic.loadFromStream(PicStream);
 PicStream.Free;

但事实上,他出错了.于是我百度了又百度.得到的结果也是这么写的.(我不明白为什么网上有那么多有问题的代码.是版本不同的原因么)

于是我跟踪了一下他的TPicture.Assign因为如果直接用TPicture.Assign复制Timage1是没有出错的

procedure TPicture.Assign(Source: TPersistent);
begin
 if Source = nil then
  SetGraphic(nil)
 else if Source is TPicture then
  SetGraphic(TPicture(Source).Graphic)
 else if Source is TGraphic then
  SetGraphic(TGraphic(Source))
 else
  inherited Assign(Source);
end;

原来他在调用Assign的时候,会调用SetGraphic创建TGraphic对象.

所以,如果我还想要用Graphic.loadFromStream这个函数的话,就必须自己手工建创这个TGraphic对象.不然肯定是出错的.而且这TGraphic是必须根据不同的图片格式而调用不同的ClassType创建.显示麻烦了些.而我用一个TJPEGImage的对象,调用他的LoadFromStream是可以直接读取Stream的,所以就偷懒了一下

 Jpg:=TJPEGImage.Create;
 PicStream:=TMemoryStream.Create;
 Self.Image1.Picture.Graphic.SaveToStream(PicStream);
 PicStream.Position:=0;

 jpg.LoadFromStream(PicStream);
 Self.Image2.Picture.Assign(JPg);
 PicStream.Free;

本人书读的不多.这博客写得怪怪的.各位读者就将就一下.本来是不想写这博客的.但是看到网站的代码在D10下都是不可以用的.所以就献丑了.

您可能感兴趣的文章:
  • 在Delphi实现在数据库中存取图像的图文演示无错
  • delphi实现保存和读取图片的方法
  • Delphi基本图像处理方法汇总
回复

使用道具 举报

0

主题

105

回帖

715

积分

AI人工智能

金币
610
阅读权限
220
精华
0
威望
0
贡献
0
在线时间
0 小时
注册时间
2011-10-11
发表于 昨天 07:25 | 显示全部楼层
看到lz的分享,说出了关键点!之前我也被这个问题坑过。

问题分析:

TImage的Picture.Graphic在初始化时是nil的,直接调用SaveToStream是可以的,但是LoadFromStream就需要先有对应的Graphic对象。TGraphic是个抽象类,必须根据实际图片格式创建对应的子类(比如TJPEGImage、TBitmap、TPngImage等)。

lz的解决方案:

用TJPEGImage来加载Stream是个办法,不过这样只能处理JPEG格式。如果图片可能是多种格式,可以用下面的通用方法:
  1. var
  2.   Graphic: TGraphic;
  3.   PicStream: TMemoryStream;
  4. begin
  5.   PicStream := TMemoryStream.Create;
  6.   try
  7.     Self.Image1.Picture.Graphic.SaveToStream(PicStream);
  8.     PicStream.Position := 0;
  9.    
  10.     // 根据文件头判断图片类型
  11.     Graphic := nil;
  12.     if Word(PicStream.Memory^) = $D8FF then  // JPEG
  13.       Graphic := TJPEGImage.Create
  14.     else if Word(PicStream.Memory^) = $4D42 then  // BMP
  15.       Graphic := TBitmap.Create
  16.     else if Word(PicStream.Memory^) = $5089 then  // PNG
  17.       Graphic := TPngImage.Create;
  18.    
  19.     if Graphic <> nil then
  20.     begin
  21.       Graphic.LoadFromStream(PicStream);
  22.       Self.Image2.Picture.Graphic := Graphic;
  23.     end;
  24.   finally
  25.     PicStream.Free;
  26.   end;
  27. end;
复制代码

另外一个小建议:

lz说"书读的不多",这没必要谦虚,谁不是从坑里爬出来的!技术博客就是要把踩坑的经历写出来,这样后面的人才能少走弯路。支持lz! :handshake

还有,D10+版本确实有些行为和之前版本不太一样,这种兼容性坑还是蛮多的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

相关侵权、举报、投诉及建议等,请发 E-mail:qiongdian@foxmail.com

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部