下面通过详细的例子来讲述如何在delphi中处理sql server中的image、text字段。因为实际开发的需要, 我们需要处理的是text类型的字段,包括读和写。网上很多相关的文章都是讲述的对image的读写操作,下面首先介绍如何将图象存储在sql server的image字段。
其中 DataMConn为一个针对数据库操作的单元,放置一个ADOConnection,一个ADOQuery //image to database
procedure TfrmText.Button1Click(Sender: TObject); var
bm:tbitmap;
ms:TMemoryStream; begin
ms:=TMemoryStream.Create;
bm:=TBitmap.Create;
bm.Assign(image1.Picture.Bitmap); bm.SaveToStream(ms);
with DataMConn.ADOQHistory do begin Close; SQL.Clear;
SQL.Add('INSERT INTO Package(PackageID,TempPackage) VALUES(:x,:y)');
Parameters.ParamByName('y').LoadFromStream(ms,ftBlob); Parameters.ParamByName('x').Value := 'aaaaa'; ExecSQL; end; end;
//show image
procedure TfrmText.Button2Click(Sender: TObject); var
Stream:TStream; bm:tbitmap; begin
with DataMConn.ADOQHistory do begin Close; SQL.Clear;
SQL.Add('SELECT * FROM Package WHERE packageID= ''aaaaa''');
Try Open; stream
pPackage'),bmRead);
bm:=TBitmap.Create;
bm.LoadFromStream(stream); image2.Picture.bitmap.Assign(bm); stream.Free; except begin
ShowMessage('Error!'); Exit; end; end;//try end; end;
下面的两个例子是如何处理text类型的字段,其中读取的时候,利用了一个TDBMemo控件,来加载读取的流数据,然后赋值给一个
:=
DataMConn.ADOQHistory.CreateBlobStream(FieldByName('Tem
WideString类型的变量str
//text to stream
procedure TfrmText.Button3Click(Sender: TObject); var
str : WideString; ss:TStringStream; i : integer; begin
str := 'sstrstrststrstrststrstrstrsttrstrstrrstrstr'; for i := 1 to 10000 do begin
str := str + 'sstrstrststrstrststrstrstrsttrstrstrrstrstr'; //43万多个字节
end;
str := str + 'E';
ss := TStringStream.Create(str); //bm:=TBitmap.Create;
//bm.Assign(image1.Picture.Bitmap); //bm.SaveToStream(ms);
with DataMConn.ADOQHistory do begin Close; SQL.Clear;
SQL.Add('INSERT INTO tPackage(PackageID,TempPackage) VALUES(:x,:y)');
Parameters.ParamByName('y').LoadFromStream(ss,ftMemo); Parameters.ParamByName('x').Value := 'aaaaa'; ExecSQL; end; end;
//read text to a TDBMemo
procedure TfrmText.Button4Click(Sender: TObject); var
stream : TStream; str : WideString; begin
with DataMConn.ADOQHistory do begin Close; SQL.Clear;
SQL.Add('SELECT TempPackage FROM tPackage WHERE packageID= ''aaaaa''');
Open;
if not IsEmpty then begin Stream
pPackage'),bmRead);
stream.Position := 0;
AMemo.Lines.LoadFromStream(stream); stream.Free; end; end; end;
//下面是把text字段的数据内容直接读到一个WideString中,而不通过TDBMemo,因为在实际中,不知道何种原因,线程读到数据后,只能在第一次处理时正常,然后再用鼠标点应用程序,程序就停了……who knows the reason , pls tell me & 3ks
procedure TfrmText.Button5Click(Sender: TObject);
:=
DataMConn.ADOQHistory.CreateBlobStream(FieldByName('Tem
var
Buffer: PChar; MemSize: Integer; Stream: TStream; str : WideString; begin
with DataMConn.ADOQHistory do begin Close; SQL.Clear;
SQL.Add('SELECT TempPackage FROM tPackage WHERE packageID= ''aaaaa''');
Open;
if not IsEmpty then begin Stream
pPackage'),bmRead);
try
MemSize := Stream.Size;
Inc(MemSize); //Make room for the buffer's null terminator. Buffer := AllocMem(MemSize); //Allocate the memory. try
Stream.Read(Buffer^, MemSize); //Read TempPackage field into buffer.
str := Buffer; finally
FreeMem(Buffer, MemSize); end; finally
:=
DataMConn.ADOQHistory.CreateBlobStream(FieldByName('Tem
Stream.Free; end; end; end; end;
如何用流的方法向SQLServer数据库中读写blob的image字段 var
TempStream: TMemoryStream; begin //Read
TempStream := TMemoryStream.Create; try
TBlobField(FieldByName('ImageField')).SaveToStream; TempStream.Position := 0;
Memo1.Lines.LoadFromStream(TempStream); Finally
TempStream.Free; end; //Write
TempStream := TMemoryStream.Create; try
Memo1.Lines.SaveToStream(TempStream);
//Image1.Picture.Bitmap.LoadFromStream(TempStream); TBlobField(FieldByName('ImageField')).LoadFromStream; Finally
TempStream.Free; end; end;
var
aStream1 : TStream;
jpg : tjpegimage; //在uses 加入 jpeg,db 单元 插入
jpg := tjpegimage.Create(); try
dm.Query_image.open; dm.query_image.insert; aStream1
me('content'),bmReadWrite);
jpg.LoadFromFile(name); jpg.SaveToStream(aStream1); aStream1.Free; dm.query_image.Post; finally jpg.Free; end; 取出
if dm.query_image.State <> dsBrowse then exit;
if dm.query_image.FieldByName('content').IsNull then Exit; //判断状态,content是我表里存放jpeg的field
dm.query_image.open;
:=
dm.query_image.CreateBlobStream(dm.query_image.FieldByNa
aStream1
me('content'), bmRead);
try
aStream1.Position := 0; jpg:= tjpegimage.Create(); try
jpg.LoadFromStream(aStream1);
jpg.SaveToFile(ipath); //ipath:string 存放路径与文件名 finally jpg.Free; end; finally
aStream1.Free; end; end;
文件写入字段:
:=
dm.query_image.CreateBlobStream(dm.query_image.FieldByNa
SQLstr:='INSERT INTO 表名 (...,Image字段名,...)VALUES (...,:Image,...)';
Query.SQL.Add(SQLstr);
Query.SQL.ParamByName('Image').LoadFromFile(图象文件名); Query.ExecSQL;
从字段写入文件:
SQLstr:='SELECT ...,Image字段名,... FROM 表名 WHERE...'; Query.Close; Query.SQL.Clear;
Query.SQL.Add(SQLstr); Query.Open;
(Query.FieldByName(ImageTBlobField).SaveToFile(文件名);
//
或
TBlobField(Query.FieldByName(Image
字
段
名)).SaveToFile(文件名);
向SQL Server插入带有Image字段的记录
向SQL Server插入记录相信大家都会做,但是如果表中带有Image字段就不好弄了,这里有一个例子,非常安全,同时也向大家展示动态生成控件的技巧!
在SQL Server中建立TEST表,两个字段,id varchar(10),photo image(16);
procedure TForm1.BitBtn1Click(Sender: TObject); begin
openpicturedialog1.execute;
image1.picture.loadfromfile(openpicturedialog1.filename); end;
procedure TForm1.BitBtn2Click(Sender: TObject); var
graphic1:Timage; begin
graphic1:=Timage.Create(self);
graphic1.picture.loadfromfile(openpicturedialog1.filename); table1.Open; table1.insert;
table1.fieldbyname(’id’).asstring:=’121’; table1.fields[1].assign(graphic1.Picture);
字
段
名
)
as
table1.post; table1.close; graphic1.free; end;
显示可用:
DBIMAGE控件显示!
DELPHI存取JPEG文件到SQL Server数据库
unit Unit1;
interface uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, DBCtrls, Grids, DBGrids, Db, ADODB,jpeg, StdCtrls,dbtables;
{一定要USES JPEG单元,使能存储JPG文件格式} type
TForm1 = class(TForm) DataSource1: TDataSource; ADOQuery1: TADOQuery; DBGrid1: TDBGrid;
DBNavigator1: TDBNavigator; Image1: TImage; savebutton: TButton; showbutton: TButton; OpenDialog1: TOpenDialog;
ADOQuery1id: TIntegerField; ADOQuery1pic: TBlobField;
procedure savebuttonClick(Sender: TObject); procedure showbuttonClick(Sender: TObject);
procedure DBNavigator1Click(Sender: TObject; Button: TNavigateBtn);
private
{ Private declarations } public
{ Public declarations } end; var
Form1: TForm1;
implementation
{$R *.DFM}
function JpegStartsInBlob(PicField:TBlobField):integer; var
ghy: TADOBlobstream; buffer:Word; hx: string; begin Result := -1;
ghy := TADOBlobstream.Create(PicField, bmRead); try
while (Result = -1) and (ghy.Position + 1 < ghy.Size) do begin
ghy.ReadBuffer(buffer, 1); hx:=IntToHex(buffer, 2); if hx = ’FF’ then begin ghy.ReadBuffer(buffer, 1); hx:=IntToHex(buffer, 2);
if hx = ’D8’ then Result := ghy.Position - 2 else if hx = ’FF’ then ghy.Position := ghy.Position-1; end; //if end; //while finally ghy.Free end; //try end;
procedure TForm1.savebuttonClick(Sender: TObject); var
picstream:tadoblobstream; begin
adoquery1.edit;
picstream:=tadoblobstream.Create(tblobfield(adoquery1.fields[1]),bmWrite);
if form1.opendialog1.execute then begin
picstream.LoadFromFile(opendialog1.filename); picstream.Position:=0; adoquery1.edit;
tblobfield(adoquery1.Fields[1]).loadfromstream(picstream); adoquery1.post;
end; end;
procedure TForm1.showbuttonClick(Sender: TObject); var
ghy:TADOBlobstream; pic:tjpegimage; begin
ghy := TADOBlobstream.Create(Adoquery1pic, bmRead); try
ghy.Seek(JpegStartsInBlob(Adoquery1pic),soFromBeginning);
Pic:=TJpegImage.Create; try
Pic.LoadFromStream(ghy); Image1.Picture.Graphic:=Pic; finally Pic.Free; end; finally ghy.Free end; end;
procedure begin
if button in [nbFirst, nbPrior, nbNext, nbLast] then
TForm1.DBNavigator1Click(Sender:
TObject;
Button: TNavigateBtn);
showbutton.Click;
end; end.
如果数据库中要存储的是BMP文件,则在procedure TForm1.showbuttonClick(Sender: TObject);过程中代码更改如下即可存储显示BMP文件格式的操作。
procedure TForm1.showbuttonClick(Sender: TObject); var
ghy:TADOBlobstream; pic:tbitmap; begin
ghy := TADOBlobstream.Create(Adoquery1pic, bmRead); try
{ ghy.Seek(JpegStartsInBlob(Adoquery1pic),soFromBeginning);}
Pic:=Tbitmap.Create; try
Pic.LoadFromStream(ghy); Image1.Picture.Graphic:=Pic; finally Pic.Free; end; finally ghy.Free end; end;
将JPG格式图片保存到ACCESS数据表中 var
Ind,i:Integer; FName:string; AJPeg:TJPEGImage; temp:TBitmap; begin
if opd1.Execute then begin
btnAdd.Enabled:=False; Ind:=Opd1.Files.Count; for i:=0 to Ind-1 do begin
FName:=opd1.Files.Strings; Application.ProcessMessages; tbl1.Append;
tblPictureName.AsString:=FName; if UpperCase(Copy(FName,Length(Fname)-3,4))=’.JPG’
then
begin
AJpeg:=TJPEGImage.Create; AJpeg.LoadFromFile(FName); Temp:=TBitmap.Create; Image1.Height:=Ajpeg.Height; Image1.Width:=Ajpeg.Width; Image1.Picture:=nil;
Image1.Canvas.Draw(0,0,Ajpeg); DBImage1.Picture:=Image1.Picture; AJpeg.Free; end else
tblPicture.LoadFromFile(FName);
tbl1.Post; end; end; 说明:
tbl1:TADOQuery;
opd1:TOpenPictureDialog;
tblPicture是tbl1的字段,OLE型。 uses JPEG;
delphi数据库图片的存取
一、 原理介绍--流式数据的类型及其应用
在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。
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; //搞定
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
nb.SaveToFile(SaveDialog1.FileName);
nb.Free;
then
end; b.Free; end;
因篇幅问题不能全部显示,请点此查看更多更全内容