【问题标题】:Delphi load image save as blob in a sql databaseDelphi加载图像保存为sql数据库中的blob
【发布时间】:2014-11-24 01:18:57
【问题描述】:

我正在尝试从以前保存在 sql 数据库中的图像 blob 加载图像控件。我已经测试了很多方法,但我无法使其工作。图像 blob 保存为:

qry.SQL.Text := 'update tbl set pic = :blobVal where id = :idVal';
qry.Parameters.ParamByName('blobVal').LoadFromFile('c:\sample.jpg', ftBlob);
qry.Parameters.ParamByName('idVal').Value := 1;

有什么建议吗?

【问题讨论】:

  • 请添加更多详细信息,我们所说的是 SQL 服务器吗?您的 qry 变量代表什么组件?

标签: sql image delphi blob


【解决方案1】:

这里有很多关于将图像加载为数据库的方法,但我没有找到带有更新或插入参数的方法。

您可以简单地将图形对象分配给您的参数。 如果要存储不同的图形类型,则应添加一列 保留应存储哪种图形的信息(例如 jpeg、bmp、png)。 如果您想从数据库中检索图片,则能够创建所需的 TGraphic 类后代。

uses jpeg, pngimage;

type
 TitTYPES=(itJPG,itPNG,itBMP);

procedure TDEMO.Button1Click(Sender: TObject);
var
 jp:TJpegimage;
 g:TGraphic;
begin

  jp:=TJpegimage.Create;
  try
    ads.Close;
    jp.LoadFromFile('C:\Bilder1\PIC.jpg');
    ads.SQL.Text := 'Insert into IMGBlob (ID,Blob,typ) Values (:ID,:BLOB,:typ)';
    ads.Parameters[0].Value := 1;
    ads.Parameters[1].Assign(jp);
    ads.Parameters[2].Value := itJPG;
    ads.ExecSQL;

    ads.SQL.Text := 'Select * from IMGBlob where ID=:ID';
    ads.Parameters[0].Value := 1;
    ads.Open;
    try
      case TitTYPES(ads.FieldByName('typ').AsInteger) of
           itJPG: g:=TJpegimage.Create;
           itPNG: g:=TPNGImage.Create;
           itBMP: g:=TBitmap.Create;
      end;
    g.Assign(ads.FieldByName('Blob'));
    Image1.Picture.Assign(g);
    finally
      g.Free;
    end;
  finally
    jp.Free;
  end;
end;

【讨论】:

  • 它可以正常工作,因为内部 TBlobField 使用 IStreamPersist 接口分配图像。
【解决方案2】:

要将 BLOB 字段加载到图像中,您需要使用 TDataSet.CreateBlobStream。

var
  Stream: TStream;
  JPG: TJpegImage;
begin
  JPG := TJpegImage.Create;
  try
    Stream := Qry.CreateBlobStream(Qry.FieldByName('BLOBVAL'), bmRead);
    try
      JPG.LoadFromStream(Stream);
    finally
      Stream.Free; // edited
    end;
  finally
    JPG.Free;
  end;
end;

要将图像存储回来,您需要执行相反的操作:

var
  Stream: TBlobStream;
  Jpg: TJpegImage;
begin
  Jpg := TJpegImage.Create;
  try
    Jpg.Assign(Image1.Picture.Graphic);
    // Assign other query parameters here
    Stream := Qry.CreateBlobStream(Qry.FieldByName('BLOBVAL'), bmWrite);
    try
      Jpg.SaveToStream(Stream);
      Qry.ExecSQL;
    finally
      Stream.Free;
    end;
  finally
    Jpg.Free;
  end;
end;

TDBImage 仅设计用于位图(当字段为ftGraphic 时),因此不能直接用于 JPEG 图像。最简单的做法是将 blob 加载为 JPEG,并将其分配给数据集事件处理程序中的标准 TImage.Picture.Graphic(例如 AfterScroll 事件)。

【讨论】:

    【解决方案3】:

    保存到数据库:

    var
      ms:tmemorystream;
    Begin  
      ms:=tmemorystream.create;
      ms.position:=0;
      image1.picture.bitmap.savetostream(ms);
      ms.position:=0;
      with yourfield as tblobfield do
        loadfromstream(ms);
      freeandnil(ms);
    end; 
    

    从数据库加载:

    var
      ms:tmemorystream;
    Begin  
      ms:=tmemorystream.create;
      ms.position:=0;
      with yourfield as tblobfield do
        savetostream(ms);
      ms.position:=0;
      image1.picture.bitmap.loadfromstream(ms);
      freeandnil(ms);
    end; 
    

    【讨论】:

    • 很高兴在这里看到try..finally 块,而不是对于本地对象毫无意义的FreeAndNil
    【解决方案4】:

    它不适用于所有图形类型,如 PNG 等。

    这个也适用于 PNG:

    var mBitmap : TGraphic;
    var mStream : TStream;
    var mClass  : TGraphicClass;
    begin
          mStream := Query.CreateBlobStream(Query.FieldByName('yourBlobfield'), bmRead);
          mClass  := GetGraphicClassForFileExtension(mStream.ReadAnsiString);
          mBitmap := mClass.Create;
          mBitmap.LoadFromStream(mStream);
          Image4.Picture.Assign(mBitmap);
     end;   
    

    【讨论】:

      猜你喜欢
      • 2015-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-08
      • 2023-03-15
      • 2013-12-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多