一、 原理介绍--流式数据的类型及其应用 在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;
|
请发表评论