我的SQL数据库,员工照片表三个字段,一个:照片类型 varchar(10),照片 image,员工ID varchar(10)
保存:
var
FileName, ls_filehz_name: string;
StringStream1: TStringStream;
jpeg1: TJPEGImage;
begin
if OpenDialog1.FileName <> '' then
begin
FileName := OpenDialog1.FileName;
ClientDataSet1.Close;
ClientDataSet1.CommandText := 'insert into 员工照片表(照片类型,照片,员工ID) values(:a,:b,:c)'; //取得打开的图象文件的后缀名
ls_filehz_name := copy(ExtractFileExt(FileName), 2, 3);
ClientDataSet1.Params.ParamByName('a').AsString := ls_filehz_name; //当图象文件格式为bmp时
if ls_filehz_name = 'bmp' then
begin
ClientDataSet1.Params.ParamByName('b').Assign(Image1.Picture);
ClientDataSet1.Params.ParamByName('c').AsString := Frm_main.user_ID;
ClientDataSet1.Execute;
end; //当图象文件格式为jpg时
if ls_filehz_name = 'jpg' then
begin
StringStream1 := TStringStream.Create(' ');
jpeg1 := TJPEGImage.Create;
jpeg1.Assign(Image1.Picture);
jpeg1.SaveToStream(StringStream1);
ClientDataSet1.Params.ParamByName('pic').AsBlob := StringStream1.DataString;
ClientDataSet1.Params.ParamByName('c').AsString := Frm_main.user_ID;
ClientDataSet1.Execute;
StringStream1.free;
jpeg1.free;
end;
end;
我现在只试一下读BMP,但总是出现 stream read error..这是怎么回事的?
读图片代码:
var
bs: TMemoryStream;
begin
with ClientDataSet1 do
begin
Close;
CommandText := 'select * from 员工照片表 where 员工ID='''+frmmain.user_ID+'''';
Open;
end;
bs := TMemoryStream.Create;
(ClientDataSet1.FieldByName('照片') as TBlobField).SaveToStream(bs);
bs.position := 0;
Image1.Picture.Bitmap.LoadFromStream(bs);
bs.free;
调试到这句:Image1.Picture.Bitmap.LoadFromStream(bs);
就出现错误了,stream read error.
这个问题error我很长时间了,哪位>能说一下?谢谢!
保存:
var
FileName, ls_filehz_name: string;
StringStream1: TStringStream;
jpeg1: TJPEGImage;
begin
if OpenDialog1.FileName <> '' then
begin
FileName := OpenDialog1.FileName;
ClientDataSet1.Close;
ClientDataSet1.CommandText := 'insert into 员工照片表(照片类型,照片,员工ID) values(:a,:b,:c)'; //取得打开的图象文件的后缀名
ls_filehz_name := copy(ExtractFileExt(FileName), 2, 3);
ClientDataSet1.Params.ParamByName('a').AsString := ls_filehz_name; //当图象文件格式为bmp时
if ls_filehz_name = 'bmp' then
begin
ClientDataSet1.Params.ParamByName('b').Assign(Image1.Picture);
ClientDataSet1.Params.ParamByName('c').AsString := Frm_main.user_ID;
ClientDataSet1.Execute;
end; //当图象文件格式为jpg时
if ls_filehz_name = 'jpg' then
begin
StringStream1 := TStringStream.Create(' ');
jpeg1 := TJPEGImage.Create;
jpeg1.Assign(Image1.Picture);
jpeg1.SaveToStream(StringStream1);
ClientDataSet1.Params.ParamByName('pic').AsBlob := StringStream1.DataString;
ClientDataSet1.Params.ParamByName('c').AsString := Frm_main.user_ID;
ClientDataSet1.Execute;
StringStream1.free;
jpeg1.free;
end;
end;
我现在只试一下读BMP,但总是出现 stream read error..这是怎么回事的?
读图片代码:
var
bs: TMemoryStream;
begin
with ClientDataSet1 do
begin
Close;
CommandText := 'select * from 员工照片表 where 员工ID='''+frmmain.user_ID+'''';
Open;
end;
bs := TMemoryStream.Create;
(ClientDataSet1.FieldByName('照片') as TBlobField).SaveToStream(bs);
bs.position := 0;
Image1.Picture.Bitmap.LoadFromStream(bs);
bs.free;
调试到这句:Image1.Picture.Bitmap.LoadFromStream(bs);
就出现错误了,stream read error.
这个问题error我很长时间了,哪位>能说一下?谢谢!
解决方案 »
- delphi中btnSwitch组件
- 如何把当前屏幕的画面图像写入一个form中?
- 跪求~~~(delphi 做的P2P原码)
- 我建三层结构,使用DcomConnection,是不是服务器端非得设成域,客户机用户非得在服务器上有权限才能使用?
- 这么简单也错,我郁闷
- 关于存储过程
- 请问:pascal 中如何定义类型
- 请问在Delphi中FormatMessage要如何用?
- DBGrid1.DefaultDrawColumnCell(rect,Field,Column,State)报错
- 如何控制:输入EDIT控件中的值能作为DATETIME格式的值,并当输入为字符时,如何处理异常?
- 【100】如何将EXCEL中的数据导入到Interbase表中,格式已经固定了
- 求adotable或adoquery的添加语句
在Dephi中提供了一个抽象的数据类型TStream来支持对流式数据的操作。这些数据通常来自文件、数据库、内存对象、OLE对象等,TStream提供了统一、简洁的方法来进行数据的读写。在通常情况下,我们并不需要直接使用TStream类,对流式数据的读写封装在VCL控件的方法中。但是如果这些方法无法满足我们的要求,就需要自己手动控制数据的读写。
一、 TStream的常用的方法和属性:
1. function Read(var Buffer; Count: Longint): Longint; virtual; abstract
2. function Write(const Buffer; Count: Longint): Longint; virtual; abstract;
3. function Seek(Offset: Longint; Origin: Word): Longint; virtual; abstract;
4. property Position: Longint;
5. property Size: Longint
Read,Write,Seek都是纯虚函数,提供了数据读写和定位的抽象的方法。Read方法将数据从Stream中读到Buffer缓冲区中,Write则实现相反的操作,返回值表示实际读写数据的大小。Seek提供了在Stream中移动数据指针的方法。参数Origin可以取soFromBeginning,soFromCurrent,soFromEnd三个值,Offset是偏移量,返回值是当前Stream数据指针的位置。
Position表示了数据指针在Stream中的位置。这个属性是可读写的,它实际上就是通过调用Seek方法实现的,所以实际使用时使用这个属性更为方便一些。Size属性表示当前Stream的大小,对于不同的Stream,有些时候是只读的。
二、 Stream数据的读写。
1. SaveToStream(Stream: TStream ); //将类中的数据写到Stream的当前位置中
2. LoadFromStream(Stream: TStream); //从当前位置读入Stream里的数据实际使用时我们基本上只要使用上面两个函数就可以了。
三、 例子
TStream的继承树图如图1所示(略),实际使用时比较常用的是TFileStream,TMemoryStream,TblobStream,就以这三种流举一例说明具体用法。
创建一个窗体Form1,放置三个按钮btnRead,btnInvert,btnSave和一个文件打开对话框OpenDialog1以及数据控件DataSource1,Table1,test.
使用Dephi提供的Database Desktop创建一个表test,表里有一个字段域Image,数据库文件名存为test.db。在窗体上放置一个TDatabase控件dbTest,一个TTable控件Table1,一个DataSource控件DataSource1,一个TDBNavigator控件DBNavigator1。将dbTest与刚才Desktop创建的数据库相连,Table1的TableName属性设为test.db,DataSource1的DataSet属性设为Table1,DBNavigator1的DataSource属性设为DataSource1,VisibleButtons属性前四个设为TRUE。此外,将dbtest的Connected设为TRUE,Table1的Active属性设为TRUE,使得数据库一开始就处于打开状态。事件代码编写如下:
1. btnRead的Click事件,这里演示了TFileStream的用法。 var
MS: TFileStream;
begin
if OpenDialog1.Execute then
begin
MS:=TFileStream.Create(OpenDialog1.FileName, fmOpenRead);
Image1.Picture.Bitmap.LoadFromStream(MS);
MS.Free;
end;
end;
2. btnInvert的Click事件,这里演示了TMemoryStream的用法。其中使用了Invert函数,这是一个简单的将图象反色的函数(仅对真彩图象有效),它返回一个指向处理过的图象数据块的指针。 var
MS: TMemoryStream;
pImage: pointer;
begin
MS:=TMemoryStream.create;
Image1.Picture.Bitmap.SaveToStream(MS);
MS.Position:=0;
pImage:=Invert(MS.Memory, MS.size);
//Memory属性是指向实际内存块的指针
MS.Write(pImage^,MS.size);
MS.Position:=0;
//上一行代码使指针移到了Stream末尾,所以要复位
Image1.Picture.Bitmap.LoadFromStream(MS);
FreeMem(pImage);
MS.Free;
end;
Invert函数如下:function TForm1.Invert(pImage: pointer; size: Integer): pointer;
var
pData, pMem: PChar;
i: Integer;
begin
pMem:=AllocMem(size);
CopyMemory(pMem,pImage,size);
pData:=pMem+54;
for i:=0 to size541 do
begin
pData^:=Char(not integer(pData^));
pData:=pData+1;
end;
Result:=pMem;
end;
3. btnSave的Click事件,这里演示了TMemoryStream的另一种用法,将Stream中的数据写到数据库中去。 var
MS: TMemoryStream;
begin
MS:=TMemoryStream.create;
Image1.Picture.Bitmap.SaveToStream(MS);
MS.Position:=0;
Table1.Append;
//在数据库中添加一条记录
TBlobField(Table1.FieldbyName('image')).LoadFromStream(MS);
Table1.Post;
//将所作的更新写入数据库
end;
4. DBNavigator1的Click事件,这里演示了TBlobStream的用法,使用了和写入时不同的方法来读出数据库的图象数据。 var
MS: TStream;
begin
with Table1 do
MS:=CreateBlobStream(FieldbyName('image'),bmRead);
Image1.Picture.Bitmap.LoadFromStream(MS);
MS.Free;
end;
现在你已经能够在文件,数据库,内存中任意读写数据流了。试试看吧!
//1.确保你的SQL语句正确,你的SQL语句可能有错,
//2.确保你的文件格式为BMPvar
bs: TMemoryStream;
begin
with ClientDataSet1 do
begin
Close;
CommandText := 'select * from 员工照片表 where 员工ID='''
+ frmmain.user_ID + ''';
Open;
end;
//当查询没有记录时,则返回
if ClientDataSet1.RecordCount = 0 then Exit; bs := TMemoryStream.Create;
(ClientDataSet1.FieldByName('照片') as TBlobField).SaveToStream(bs);
bs.position := 0;
Image1.Picture.Bitmap.LoadFromStream(bs);
bs.free;
end;从你的程序来看,你的错误可能是第1点所造成的,也就是说,
你可能并没有找到任何记录,所以会出现内存错误
但是,我OPEN 后if ClientDataSet1.FieldByName('照片').AsString='' then Exit;发现不为空呀~
就是里面有值了,但为什么会出错了呢>..>>>是不是没保存完?还是什么?郁闷啦.....
各位弟兄.帮我出点策略
//存储图片
MyJPEG := TJPEGImage.Create;
try
with MyJPEG do
begin
Assign(Image1.Picture.Graphic);
MS:=TMemoryStream.create;
SaveToStream(MS);
MS.Position:=0;
TBlobField(FieldbyName('图片')).LoadFromStream(MS);
end;
finally
MyJPEG.Free;
end;
try
Post;
except
showmessage('数据无法提交');读取图片的代码:
if ef_adoquery.RecordCount<>0 then
begin
try
tempstream:=TmemoryStream.Create();
//将图像字段保存到流中
TBlobField(mainform.ef_ADOQuery.FieldByName('图片')).SaveToStream(tempstream);
////给留定位
tempstream.Position:=0;
//省城临时image
tempjpeg:=TJPEGImage.Create;
//存留信息
tempjpeg.LoadFromStream(tempstream);
//显示图像
Image1.Picture.Bitmap.Assign(tempjpeg);
finally
tempstream.Free;
tempjpeg.Free;
end;
end;
能解决你的问题吧:)
begin
//可能問題出在下面的這句
//樓主先把你的圖形保存到流中,再調入流,來試一下
ClientDataSet1.Params.ParamByName('b').Assign(Image1.Picture);
ClientDataSet1.Params.ParamByName('c').AsString := Frm_main.user_ID;
ClientDataSet1.Execute;
end;