http://blog.sina.com.cn/s/blog_693cf1cf0100plkq.html
对于涉及图像数据的数据库应用程序,图像数据的存取技术是一个关键。由于缺少技术文档及DEMO例程演示,为此笔者在网上搜索了相关资料,有的根本不能用,有的过于繁杂,有的应用范围太窄(如只能适用于BMP图像),有的写得过于简单理解起来十分困难。。。而且在网上这也是大家比较关心的一个问题。笔者对这个问题进行了反复实作和探索,下边笔者将通过一个完整的简单例子来说明如何保存和显示SQL数据库中的图像数据(同时包括BMP和JPEG两种格式)。
一、 创建演示数据库
在SQL SERVER中新建一演示数据库:Demo,并创建一数据表Picture1,结构如下:
字段名 |
Dtata Type |
Identity |
Id |
Int |
Yes |
Isbmp |
Tinyint |
|
Myimage |
Image |
|
字段Isbmp是用来记录在Myimage中存入的图像的类型(0表JPEG,1表BMP,其它值表无图像),Isbmp数据类型选用整型Tinyint而末选用逻辑bit型主要是考虑到如下方法仍适用于ACCESS数据库。在SQL中打开表Picture1,添入几条记录,Myimage图像字段值暂不管,字段Isbmp值随便输入0和1之外的其它数。
二、 窗口设计
在DELPHI中新建一个工程,在FORM1上放置如表所示控件(考虑到TDBImage型控件不能正确显示JPEG型图像,所以选用Timage型控件显示所有类型图像)。
组件类别 |
组件属性名 |
属性值 |
用途说明 |
Timage |
caption |
Image1 |
显示图像 |
name |
Image1 |
Stretch |
True |
Tbutton |
caption |
选择图像 |
选择图像 |
name |
selectimage |
Tbutton |
caption |
保存图像 |
保存图像到数据库 |
name |
savetodb |
TADOConnection |
caption |
Adoconnection1 |
创建与数据库demo的连接 |
name |
Adoconnection1 |
Connectionstring |
见备注 |
Connected |
True |
Loginprompt |
False |
Tadotable |
Caption |
Adotable1 |
建立与表Picture1的连接 |
name |
Adotable1 |
Connection |
Adoconnection1 |
Tablename |
Picture1 |
Active |
True |
Tdatasource |
Name |
Datasource1 |
建立数据源 |
Dataset |
Adotable1 |
Topenpicturedialog |
Caption |
Openpicturedialog1 |
选择图像文件 |
Name |
Openpicturedialog1 |
Tdbgrid |
Caption |
Dbgrid1 |
显示记录 |
Name |
Dbgrid1 |
Datasource |
Datasource1 |
备注:
adoconnection1.connectstring :=
'Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initial Catalog=demo;
Data Source=Mysqlserver'
Mysqlserver为SQL服务器的名称请据实际情况更改。
三、 程序代码(首先在单元文件接口部分的uses语句中添入JPEG单元引用)
1. 图像数据的选择及保存
procedure TForm1.selectimageClick(Sender: TObject); //选择图像 begin if openpicturedialog1.Execute then image1.Picture.LoadFromFile(openpicturedialog1.FileName ); end; procedure TForm1.savetodbClick(Sender: TObject); //保存图像 var strm:tmemorystream; ext:string; begin if image1.picture.Graphic <> nil then //避免image1中无图像保存出错 begin ext:=extractfileext(openpicturedialog1.FileName ); //取出文件的扩展名 strm := tmemorystream.Create ; try image1.Picture.Graphic.SaveToStream(strm); adotable1.Edit ; strm.Position :=0; tblobfield(adotable1.FieldByName('myimage')).LoadFromStream(strm); //如需直接由文件保存可采用如下注释行 //TBlobField(adotable1.FieldByName('myimage')).LoadFromFile(OpenPictureDialog1.FileName); //以下记录保存到数据库的图像格式 if uppercase(ext) = '.BMP' then adotable1.FieldByName('isbmp').Value := 1 //BMP型图像数据 else if (uppercase(ext) = '.JPG') OR ( uppercase(ext) = '.JPEG') Then adotable1.FieldByName('isbmp').Value := 0; //JPEG型图像数据 adotable1.Post ; finally strm.Free ; //笔者发现如strm采用tblobstream类,程序运行到该语句会出现问题 end; end; end;
2. 图像数据的读取及显示
从数据库图像字段中读取数据然后在Image1中把图像显示出来的程序代码,笔者先尝试在Datasource1的OnDataChange事件中来完成,但会出错,后改写在adotable1的afterscroll事件中顺利完成。
procedure TForm1.adoTable1AfterScroll(DataSet: TDataSet); //显示图像 var strm:tadoblobstream; jpegimage:tjpegimage; bitmap:tbitmap; begin strm := tadoblobstream.Create(tblobfield(adotable1.fieldbyname('MYIMAGE')),bmread); try //try1 strm.position :=0; image1.Picture.Graphic := nil; //清除图像 // BMP、JPEG两种图像数据必需分别处理 if adotable1.fieldbyname('isbmp').asstring ='1' then //BMP型图像数据 begin //begin11 bitmap := tbitmap.Create ; try //try11 bitmap.LoadFromStream(strm); image1.Picture.Graphic := bitmap; finally bitmap.Free; end; //end try11 end //end begin11 else if adotable1.fieldbyname('isbmp').asstring ='0' then //JPEG型图像数据 begin //begin12 jpegimage := tjpegimage.Create ; try //try12 jpegimage.LoadFromStream(strm); image1.Picture.Graphic := jpegimage; finally jpegimage.Free ; end; //end try12 end; //end begin12 finally strm.Free ; end; //end try1 end;
如果你想将数据库中的图像导出到外部文件中可采用如下关键语句:
image1.Picture.SaveToFile(FileName );
以上程序代码不但适用于SQL数据库,而且完全适用于ACCESS数据库,但创建ACCESS数据库时应注意图像字段的数据类型应为OLE型,数据库创建完成之后再将Adoconnection1连接到该ACCESS数据库即可运行。欲知详细情况,请索取源程序。以上提供了DELPHI利用Tsteam类存取JPEG、BMP图像到数据库的一种解决方案,笔者争取下文介绍DELPHI利用ASSIGN方法存取JPEG、BMP图像到数据库的另一解决方案。
以上程序代码在DELPHI6.0+SQL(或ACCESS)数据库下运行通过。
Delphi图像存取另类解决方案
在前文中,提供了一种DELPHI存取JPEG、BMP图像到数据库的解决方案,虽然它适用于ACCESS和SQL数据库,但它并不适用于所有数据库(比如PARADOX数据库中的GRAPHIC图像字段就不能采用该方法存取图像数据),下文将介绍DELPHI利用ASSIGN方法存取JPEG、BMP图像到数据库的另一解决方案来进行补充完善。演示数据库结构和窗口界面设计同前文,不再重述,将单元的相应程序代码作如下更换:
1. 图像数据的选择及保存
procedure Tform1.selectimageClick(Sender: TObject); //选择图像 begin if openpicturedialog1.Execute then image1.Picture.LoadFromFile(openpicturedialog1.FileName ); end; procedure Tform1.savetodbClick(Sender: TObject); //保存图像到数据库 var ext:string; begin if image1.picture.Graphic <> nil then //避免image1中无图像保存出错 begin adotable1.Edit ; adotable1.FieldByName('myimage').Assign(image1.Picture.Graphic); //以下记录保存到数据库的图像格式 ext:=extractfileext(openpicturedialog1.FileName ); //取出文件扩展名 if uppercase(ext) = '.BMP' THEN adotable1.FieldByName('isbmp').VALUE := 1 //BMP型图像数据 ELSE IF (UPPERCASE(EXT) = '.JPEG') OR (UPPERCASE(EXT) = '.JPG') THEN adotable1.FieldByName('isbmp').VALUE := 0; //JPEG型图像数据 ADOTABLE1.Post ; end; end;
2. 图像数据的读取及显示
procedure Tform1.ADOTable1AfterScroll(DataSet: TDataSet); //ADOTable1的AfterScroll事件方法程序 var jpegimage:tjpegimage; begin image1.Picture.Graphic :=nil; //下边BMP、JPEG两种图像数据必需分别处理 if adotable1.fieldbyname('isbmp').Asstring = '1' then //BMP型图像数据 image1.Picture.bitmap.Assign(adotable1.fieldbyname('myimage')) //上边语句中的bitmap不能为graphic,否则会出错 else if adotable1.fieldbyname('isbmp').asstring = '0' then //JPEG型图像数据 begin //begin2 jpegimage := tjpegimage.Create ; //通过jpegimage将图像显示在image1,否则会出错 try jpegimage.Assign(adotable1.fieldbyname('myimage')); image1.Picture.Graphic :=jpegimage; finally jpegimage.Free ; end; //end try end; //end begin2 end;
注:别忘了在单元文件接口部分的uses语句中添入JPEG单元引用。
以上程序代码在DELPHI6.0+SQL(或ACCESS或PARADOX)数据库下运行通过。
|
请发表评论