delphi 如何實現在MS Access資料庫中影象的儲存和顯示
一、原理介紹--流式資料的型別及其應用
在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 tempstream:TStringStream;
tempjpeg:TJPEGImage;
begin
try
tempstream:=TStringStream.Create('');
TBlobField(Query1.FieldByName('Image')).SaveToStream(tempstream);
tempstream.Position:=0;
tempjpeg:=TJPEGImage.Create;
tempjpeg.LoadFromStream(tempstream);
DBImage1.Picture.Bitmap.Assign(tempjpeg);
finally
tempstream.Free;
tempjpeg.Free;
end;
end;
這段程式碼的主要作用是:首先將查詢結果中的JPEG影象格式資料儲存到TStringStream中去,
然後設定資料指標在TStringStream中的位置為0;接著從TStringStream中讀入相關資料,
並把它們賦給TDBImage.Picture.Bitmap,這樣一來就實現了將資料庫中所儲存的JPEG格式的
資料轉化為BMP格式,並在TDBImage中將影象顯示出來。最後將TStringStream和TJPEGImage
這兩個物件釋放掉。特別要注意的是不能在設計階段設定TDBImage的DataField屬性,而只能
通過寫程式碼的形式在執行階段把利用流式資料所轉化過來的新格式的影象資料賦給
TDBImage.Picture.Bitmap。
2003-10-7 11:10:00
發表評語???
2003-10-7 11:11:44 BMP格式轉化為JPEG格式uses Jpeg;
procedure CopyBmpToJpeg(BmpFile,JpegFile:string);
var
Bmp:TBitmap;
Jpeg:TJPEGImage;
begin
Bmp:=TBitmap.create;
Jpeg:= TJpegImage.Create;
try
Bmp.LoadFromFile(BmpFile);
Jpeg.Assign(Bmp);
Jpeg.SaveToFile(JpegFile);
finally
Bmp.Free;
Jpeg.Free;
end;
end;
2003-10-7 14:28:34 圖片縮放Var B:Tbitmap; //臨時點陣圖
Begin
B:=Tbitmap.Create; //建立臨時點陣圖
B.Assign(YourBitmap); //採用相同色彩深度
With B do
Begin
Width:=90; //臨時點陣圖的大小為90x90
Height:=90;
End;
B.canvas.StretchDraw(B.canvas.Cliprect,YourBitmap); //縮放適應
B.SavetoFile(YourFileName); //儲存
B.Free;
End; //搞定
2003-10-22 10:33:33 JPEG和BMP同時存入,兩種不同的方法,檔案流和記憶體流procedure TForm1.Button1Click(Sender: TObject);
var
fs:TFileStream;
MS: TMemoryStream;
Bmp:TBitmap;
MYJpeg:TJPEGImage;
begin
if OpenPictureDialog1.Execute then
begin
if ExtractFileExt(OpenPictureDialog1.FileName) = '.bmp' then
begin
Bmp:=TBitmap.create;
MYJpeg:= TJpegImage.Create;
MS:=TMemoryStream.create;
try
Bmp.LoadFromFile(OpenPictureDialog1.FileName);
with MYJpeg do
begin
Assign(Bmp);
MS.Position:=0;
SaveToStream(MS);
Table1.Edit;
TBlobField(Table1.FieldByName('ZGZP')).LoadFromStream(MS);
Table1.Post;
end;
finally
Bmp.Free;
MYJpeg.Free;
MS.Free;
end;
end
else
begin
fs:=TFileStream.Create(OpenPictureDialog1.FileName,fmOpenRead);
Try
Table1.Edit;
TBlobField(Table1.FieldByName('ZGZP')).LoadFromStream(fs);
Table1.Post;
Finally
fs.free;
end;
end;
end;
2003-11-13 21:03:18 圖片的縮放procedure TForm1.Button1Click(Sender: TObject);
var
b: TBitmap;//原圖片
nb: TBitmap;//Resize以後的圖片
r: TRect;
begin
b := TBitmap.Create;
if OpenDialog1.Execute then
begin
b.LoadFromFile(OpenDialog1.FileName);
nb := TBitmap.Create;
//你可以自己定義高度和寬度,這裡是都變成一半
nb.Height := b.Height div 2; //高度變為原來的一半
nb.Width := b.Width div 2; //寬度變為原來的一半
r.TopLeft := Point(0, 0);
r.BottomRight := Point(nb.Width, nb.Height);
with nb.Canvas do
begin
Pen.Style := psDash;
Brush.Style := bsClear;
Rectangle(0, 0, nb.Width, nb.Height);
StretchDraw(r, TGraphic(b));
end;
if SaveDialog1.Execute then nb.SaveToFile(SaveDialog1.FileName);
nb.Free;
end;
b.Free;
end;