1.ACCESS數據表名test,字段id字符,字段photo為OLE
2.在DELPHI窗體中添加ADOQuery1,OpenDialog1,Image1,Button1,Button2,Button3
設置OpenDialog1的Filter為“JPEG文件(*.jpg;*.jpeg)|*.jpg;*.jpeg”
設置Button1的Caption為“Open Image”
設置Button2的Caption為“Save Image”
設置Button3的Caption為“Show Image”
代碼如下:
procedure TForm1.Button1Click(Sender: TObject); begin if OpenDialog1.Execute then Image1.Picture.LoadFromFile(OpenDialog1.FileName); end; procedure TForm1.Button2Click(Sender: TObject); var ms:TMemoryStream; begin if Image1.Picture.Graphic <>nil then begin ms:=TMemoryStream.Create ; Image1.Picture.Graphic.SaveToStream(ms); ADOQuery1.Close; ADOQuery1.SQL.Clear ; ADOQuery1.SQL.Add('insert into test(photo) values(:photo)'); ADOQuery1.Parameters.ParamByName('photo').LoadFromStream(ms,ftBlob); ADOQuery1.execsql; Image1.Picture.Graphic:=nil ; end else showmessage('Please choose a image first!'); end; procedure TForm1.Button3Click(Sender: TObject); var ms:TMemoryStream; jpg:TJPEGImage; begin ADOQuery1.Close; ADOQuery1.SQL.Clear ; ADOQuery1.SQL.Add('select * from test'); ADOQuery1.Open; if not ADOQuery1.FieldByName('photo').IsNull then begin ms:=TMemoryStream.Create ; jpg:=TJPEGImage.Create ; TBlobField(ADOQuery1.FieldByName('photo')).SaveToStream(ms); ms.Position :=0; jpg.LoadFromStream(ms); image1.Picture.Assign(jpg); end else image1.Picture.Graphic :=nil; end;
======================================================================================
一、 原理介紹--流式數據的類型及其應用
在Dephi中提供了TStream來支持對流式數據的操作。TStream是萬流之源。
但由於它是一個抽象類,故不能被直接使用;而要使用其相應的子類,
如:TFileStream 、TStringStream、TMemoryStream、TBlobStream、
TWinSocketStream和TOleStream。TStream提供了統一、簡潔的方法來進行數據的讀寫。
1.)SaveToStream(Stream: TStream ); 作用:將類中的數據寫到Stream的當前位置中
2.)LoadFromStream(Stream: TStream); 作用:從當前位置讀入Stream里的數據
實際使用時我們基本上只要使用上面兩個函數就可以了。
二、所遇到的問題及相應的解決方法
為了節省圖像的存儲空間和使用更加方便,決定采用JPEG這種圖像格式。
(一)所遇到的問題
第一、在Delphi 5中進行畫圖所用到的組件是TImage,所生成的圖像的格式為BMP格式,
而為了節省圖像的存儲空間,圖像在數據庫里存儲的格式須為JPEG格式,這樣就產生了
圖像格式轉化的需求;而TImage本身並不直接提供這兩種圖像格式之間的轉化。
第二、怎樣將存儲在Microsoft Access數據庫中的圖像取出並且顯示出來:在Delphi 5
中,能提供這種功能的組件是TDBImage,但該組件卻存在着一個很大的缺陷:它所能顯
示的圖像類型只能是一些圖標文件,元文件和BMP文件,而不能支持JPEG格式的圖像在
該組件中的顯示;但根據實際需要,在Microsoft Access數據庫中所存儲的圖像數據卻
是以JPEG格式保存的。
(二)相應的解決方法
為了解決上述兩個問題,可以采用目前數據庫中一種名為大二分對象(BLOB--Bina
ry Large Object),它是用來處理某些特殊格式的數據的。BLOB在數據庫的表中實際上
是以二進制數據的形式存放的。為了處理BLOB字段,可以借鑒一些可視的桌面數據庫的
方法。在這里,我們選擇了通過內存流的方式來完成;使用內存流,可減少磁盤操作,
大大提高運行效率。
具體的過程和相關的程序代碼如下:
1、如何實現在Microsoft Access數據庫中的圖像存儲:
這里是利用TStream的子類TMemoryStream向Microsoft Access數據庫中存儲圖像的。
下面的這段代碼是在按了“保存”按鈕之后所觸發的事件處理程序:
procedure TForm1.Button1Click(Sender: TObject); Var MyJPEG : TJPEGImage; MS: TMemoryStream; Begin MyJPEG := TJPEGImage.Create; Try With MyJPEG do Begin Assign(Image.Picture.Graphic); MS:=TMemoryStream.create; SaveToStream(MS); MS.Position := 0; Table1.Edit; TBlobField(Table1.FieldbyName('Image')).LoadFromStream(MS); Table1.Post; Messagebox(Getactivewindow(), '圖像保存完畢!', '保存', MB_OK); End; Finally MyJPEG.Free; End; End;
在這段代碼里TStream的子類TMemoryStream利用內存流起到了將BMP格式轉化為JPEG格式
的中間橋梁的作用。
2、如何將圖像從Microsoft Access數據庫中取出並顯示出來:
下面的這段代碼是在按了“查看圖像”按鈕之后所觸發的事件處理程序:
procedure TForm1.Button1Click(Sender: TObject); Var MyJPEG : TJPEGImage; MS : TMemoryStream; Begin Try MS := TMemoryStream.Create; TBlobField(Query1.FieldByName('Image')).SaveToStream(MS); MS.Position := 0; MyJPEG := TJPEGImage.Create; MyJPEG.LoadFromStream(MS); DBImage1.Picture.Bitmap.Assign(MyJPEG); //或是Sender.Picture.Assign(MyJPEG); Finally MS.Free; MyJPEG.Free; End; End;
這段代碼的主要作用是:首先將查詢結果中的JPEG圖像格式數據保存到TMemoryStream中去,
然后設置數據指針在TMemoryStream中的位置為0;接着從TMemoryStream中讀入相關數據,
並把它們賦給TDBImage.Picture.Bitmap,這樣一來就實現了將數據庫中所存儲的JPEG格式的
數據轉化為BMP格式,並在TDBImage中將圖像顯示出來。最后將TMemoryStream和TJPEGImage
這兩個對象釋放掉。特別要注意的是不能在設計階段設置TDBImage的DataField屬性,而只能
通過寫代碼的形式在運行階段把利用流式數據所轉化過來的新格式的圖像數據賦給TDBImage.Picture.Bitmap。
BTW:用到TBlobField的時候要在接口包含DB,用到TJPEGImage時要在接口包含Jpeg