//向数据库中添加记录、刷新DBGRID、把当前记录的图片读入IMAGE
procedure TForm1.Button1Click(Sender: TObject);
var
  Stream:TStream;
begin
  DataModule2.ClientDataSet1.close;
  DataModule2.ClientDataSet1.CommandText:='insert into Test(id,pic)'+ 'values(:id,:pic)';
  DataModule2.ClientDataSet1.Params.ParamByName('id').AsString := Edit1.Text;
  DataModule2.ClientDataSet1.Params.ParamByName('pic').Assign(Image1.Picture.Bitmap);
  DataModule2.ClientDataSet1.Execute;
  DataModule2.ClientDataSet1.close;
  DataModule2.ClientDataSet1.CommandText:='select * from Test';
  DataModule2.ClientDataSet1.open;
  Stream:=DataModule2.ClientDataSet1.CreateBlobStream(DataModule2.ClientDataSet1.FieldByName('pic'), bmRead);
  Image1.Picture.Graphic.LoadFromStream(Stream);
  Stream.Free;
end;//在DBGRID中显示图片
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
  Bmp: TBitmap;
begin
  if Column.Field = DataModule2.ClientDataSet1.FieldByName('pic') then
  begin
   Bmp := TBitmap.Create;
    try
      Bmp.Assign(DataModule2.ClientDataSet1.FieldByName('pic'));
      DBGrid1.Canvas.StretchDraw(Rect,Bmp);
   finally
      Bmp.Free;
   end;
 end ;
end;
上面两段程序都莫名奇妙地出现错误’Stream read error',难道我向数据库中添加图片的代码不对?

解决方案 »

  1.   

    可能是你保存图像数据流时保存的不对!
    用BlobField.LoadFromStream保存吧
    显示的时候,用BlobField.SaveToStream读取数据流到流对象,然后用
    Image.Picture.Bitmap.LoadFromStream显示!
      

  2.   

    你的显示程序没有问题,应该是保存时有问题如何实现在数据库中图像的存储和显示
    一、 原理介绍——流式数据的类型及其应用
    在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本身并不直接提供这两种图像格式之间的转化。
    第二、怎样将存储在数据库中的图像取出并且显示出来:在Delphi 5中,能提供
    这种功能的组件是TDBImage,但该组件却存在着一个很大的缺陷:它所能显示的图像类型只能是一
    些图标文件,元文件和BMP文件,而不能支持JPEG格式的图像在该组件中的显示;但根据实际需要,
    在数据库中所存储的图像数据却是以JPEG格式保存的。
    (二)相应的解决方法
    为了解决上述两个问题,可以采用目前数据库中一种名为大二分对象(BLOB——Binary Large Object),
    它是用来处理某些特殊格式的数据的。BLOB在数据库的表中实际上是以二进制数据的形式存放的。
    为了处理BLOB字段,可以借鉴一些可视的桌面数据库的方法。在这里,我们选择了通过内存流的方式来
    完成;使用内存流,可减少磁盘操作,大大提高运行效率。
    具体的过程和相关的程序代码如下:
    1、如何实现在数据库中的图像存储:
    这里是利用TStream的子类TMemoryStream向数据库中存储图像的。下面的这段代码是
    在按了“保存”按钮之后所触发的事件处理程序:
    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、如何将图像从数据库中取出并显示出来:
    下面的这段代码是在按了“查看图像”按钮之后所触发的事件处理程序:
    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。
      

  3.   

    先SAVETOSTREAM,然后LOADFROMSTREAM
      

  4.   

    你的保存图片的代码是用的APPEND形式,我想用COMMANDTEXT的形式。
    Table1.Edit;
    TBlobField(Table1.FieldbyName('Image')).LoadFromStream(MS);
    Table1.Post;
    能不能给改改?
      

  5.   

    var
       blobsm:TStream ;
       bm:tbitmap;
       ms:TMemoryStream ;
    begin
      ClientDataSet1.close;
      ClientDataSet1.Open ;
      ClientDataSet1.Edit ;
      ms:=TMemoryStream.Create ;
      bm:=TBitmap.Create ;
      bm.Assign(image1.Picture.Bitmap);
      bm.SaveToStream(ms);
      ClientDataSet1photo.LoadFromStream(ms);
      ClientDataSet1.ApplyUpdates(-1);
      bm.Free ;
      ms.Free ;
      blobsm:=ClientDataSet1.CreateBlobStream(clientdataset1.fieldbyname('photo'),bmRead);
      bm:=TBitmap.Create ;
      bm.LoadFromStream(blobsm);
      image2.Picture.bitmap.Assign(bm);
      FreeAndNil(bm);
      

  6.   

    一个怪现象~我的sqlserver的image(photo)字段在clientdataset的execute方法执行时 (SQL :update customers set photo=:photov where...)的语句报出text 类型 image类型不匹配的异常.参数photov的类型为ftgrahpic.而且不管如何设置photov的参数类型,系统一直认为photov的类型是text...
      

  7.   

    save to databasevar
      i : integer;
      l_Guid: TGUID;
    begin
      fStream := TMemoryStream.Create;
      fStream.LoadFromFile('C:\hello.txt');
      fStream.Position := 0;
      with adoquery1 do begin
        Close;
        SQL.Clear;
        SQL.Add('insert into tab_updatefile (updatefile_content,updatefile_id) values (:y,:x)');
        Parameters.ParamByName('y').LoadFromStream(FStream,ftBlob);CreateGUID(l_Guid);
          Parameters.ParamByName('x').Value := GUIDToString(l_guid);
          ExecSQL;
      end;
      showmessage('OK');
      fStream.Free;
    end;
    load from ....with adoquery1 do begin
        Close;
        SQL.Clear;
        SQL.Add('select updatefile_content from tab_updatefile ');
        Open;
      end;
      fStream := TADOBLobStream.Create(TBlobField(ADOQuery1.FieldByName('updatefile_content')),bmRead);
      fStream.SaveToFile('D:\hello.txt');
      fStream.Free;
      showmessage('OK');字段类型 : image
    可以保存各种文件,我现在只存.exe