2

我一直在 Delphi XE3 上申请。我正在尝试将值从数据库显示到TAdvStringGrid放置在表单上的组件。我正在使用数据集来显示结果TAdvSTringGRid(代码如下)。除数据库中的图像外,所有其他值都显示完美。在预期显示图像的地方,它显示的是垃圾字符。如何在 TAdvStringGrid 的数据库中完美显示图像。

SQLConnection1: TSQLConnection;
SQLMonitor1: TSQLMonitor;
DataSource1: TDataSource;
ADOConnection1: TADOConnection;
ClientDataSet1: TClientDataSet;
AdvStringGrid1: TAdvStringGrid;
procedure Button1Click(Sender: TObject);
procedure ShowSelectResults(results: TDataSet; sg: TAdvSTringGrid);
procedure FormCreate(Sender: TObject);


procedure TForm2.FormCreate(Sender: TObject);
var
    results: TDataSet;
begin
    SQLConnection1.Params.Add('Database=E:\playdb.s3db');
    try
        SQLConnection1.Connected := true;

        SQLMonitor1.Active := True;

        SQLConnection1.Execute('Select * from plays', nil, results);


    except
        on E: EDatabaseError do
          ShowMessage('Exception raised with message' + E.Message);
    end;
    ShowSelectResults(results, advstringgrid1);
 end;

调用下面的 ShowSelectResult

procedure TForm2.ShowSelectResults(results: TDataSet; sg: TAdvStringGrid);
var
  names: TStringList;
  i,j,k, rc: Integer;
  resultsfield: variant;
  Field: TblobField;
  Stream: TStream;
  Jpg: TJPEGImage;
  Picture: TPicture;

begin
    if not results.IsEmpty then

    //Prints Data in the TAdvStringGrid
    results.First;
    j := 1;
    while not results.EOF do
    begin
      if (j>sg.rowcount) then
        sg.rowcount := sg.rowcount + 1;
      for i := 0 to results.fields.Count - 1 do
      begin
        if i=0 then

        else if i = 4 then
        //Here I want to display image from db
          Field := TBlobField(results.FieldByName(names[i]).AsString);
          Stream := results.CreateBlobStream(Field, bmRead);
          sg.CreatePicture(i, j, true, ShrinkWithAspectRatio, 20, haCenter, vaAboveText).Picture
        else
        sg.cells[i,j] := results.FieldByName(names[i]).AsString;
      end;
      results.Next;
      inc(j);
    end;
end;

问题出else if i=4在上述代码中的循环处sg.CreatePictureCreatePicture程序的格式如下所示),我想在该特定列中显示图像。

在 TAdvStringGrid 手册中,他们提到了以下在网格单元格处显示图片的方法

Grid.CreatePicture(2,3,True,Shrink,0,haLeft,vaTop).LoadFromFile(‘TST.JPG’);
procedure AddPicture(ACol,ARow: Integer;APicture:TPicture;transparent: Boolean; stretchmode:TStretchMode; padding: Integer; hal:TCellHalign; val:TCellValign);
function GetPicture(ACol,ARow: Integer): TPicture;
Grid.CreateFilePicture(2,3,True,Shrink,0,haLeft,vaTop).Filename := ‘TST.JPG’;

但是没有提到如何将它与 DataSet 一起使用。我正在弄乱 TAdvStringGRid 的 CreatePicture 过程,而不是用 DataSet 解决它。

最新发展

最后我在Bummi等学者的帮助下找到了将JPEG图像保存到memorystream然后显示的方法。

我的最新代码如下

procedure TForm2.ShowSelectResults(results: TDataSet; sg: TAdvStringGrid);
var
  names: TStringList;
  Field: TblobField;
  //Stream: TStream;
  Stream: TMemoryStream;
  //blobType := TBlobType;
  Jpg: TJPEGImage;
  Picture: TPicture;
  Image: TImage;
  Graphic: TGraphic;

Begin
    //k := results.FieldCount;
    //sg.Rowcount := rc;

    results.First;
    j := 1;
    while not results.EOF do
    begin
      if (j>sg.rowcount) then
        sg.rowcount := sg.rowcount + 1;
      for i := 0 to results.fields.Count - 1 do
      begin
        if i=0 then

        else if i = 4 then  // Column 5 for Image
          begin
           try
           if ((results.FieldByName(names[i]).AsString) <> '') then
           Begin
               Stream := TMemoryStream.Create;
               Image := Timage.Create(Self);
               Jpg := TJPEGImage.Create;
               Picture := TPicture.Create;
               Field := TBlobField(results.FieldByName('image'));
               Stream := results.CreateBlobStream(Field, bmReadWrite);
               //Field.SaveToStream(Stream);
               Stream.Position := 0;
               Jpg.LoadFromStream(Stream);
               Picture.Assign(Jpg); 

              //Jpg.LoadFromFile('C:\Sample Pictures\Cabo.jpg');
              //Picture.Assign(Jpg);

              sg.AddPicture(i,j,Picture,True,ShrinkWithAspectRatio,0,haLeft,vaTop);
            end;
           finally
              Jpg.Free;
              Stream.Free;
           end;
         end
        else
        //Prints data in other columns
        sg.cells[i.j] := results.FieldByName(names[i]).AsString;

        inc(j);
       end;   
end;

根据我的说法,现在它面临一些内存问题Jpg.LoadFromStream(Stream); It is error code JPEG Error #53,我知道只有当您尝试通过 memorystream 访问的图像已损坏但我已确保图像未损坏并显示时,才会在上面显示此类错误代码借助从类似数据库中提取的其他软件进行正确处理。我还更新了数据库中的图像。仍然为什么我得到JPEG Error #53. 问题主要在Jpg.LoadFromStream(Stream)

请注意,带有注释的代码

Jpg.LoadFromFile('C:\Sample Pictures\Cabo.jpg'); 
Picture.Assign(Jpg);
sg.AddPicture(i,j,Picture,True,ShrinkWithAspectRatio,0,haLeft,vaTop); 

当它从静态文件中提取时,它可以完美运行。问题仅出在 MemoryStream 上。如何纠正这个错误?

4

2 回答 2

4

CreateBlobStream 正在创建一个 TStream 对象,而不是一个 TMemoryStream。
由于您不想将 JPG 写入数据库,因此您应该使用 bmRead 而不是 bmReadWrite。
我不习惯 SQLite,但您必须确保您使用的是合适的二进制日期类型 (BLOB)。

  JPG := TJpegImage.Create;
  Picture:= TPicture.Create;
  try
    st := results.CreateBlobStream(TBlobField(results.FieldByName('image')), bmRead);
    try
      JPG.LoadFromStream(st);
      Picture.Assign(JPG);
      sg.AddPicture(i,j,Picture,True,ShrinkWithAspectRatio,0,haLeft,vaTop);
    finally
      st.Free;
    end;
  finally
    JPG.Free;
    Picture.Free;
  end;

为确保存储的图像确实是 JPG,您应该编写 JPG 以进行测试,例如:

var
  ms: TMemoryStream;
begin
  ads.Open;
  ads.Append;
  ms := TMemoryStream.Create;
  try
    Image1.Picture.Graphic.SaveToStream(ms); // make sure having loaded a JPG
    ms.Position := 0;
    TBlobField(ads.FieldByName('image')).LoadFromStream(ms);
  finally
    ms.Free;
  end;
  ads.Post;
end;
于 2013-09-08T08:25:26.720 回答
0

我意识到这有点晚了,但我想做出贡献。我很简单地做了以下事情,不必担心图像格式(.jpg、.png 等)。我只需创建一个 TStream 对象,将 BLOB 流加载到其中,然后从流中加载 Image。简短而甜蜜,它对我很有用。

   var
     Stream : TStream;
   begin
     try
       Stream := TStream.Create;
       Stream := Dataset.CreateBlobStream(Dataset.FieldByName('SIGNATURE'), bmRead);
       Stream.Position := 0;
       lblPicSize.Caption := 'Picture is ' + IntToStr(Stream.Size) + ' Bytes';
       if Stream.Size <= 0 then
         pnlPic.Caption := '<No Signature>'
       else
         pnlPic.Caption := '';

       try
         imgSignature.Picture.LoadFromStream(Stream);
       except
         on E:Exception do
           begin
             ShowMessage(E.Message);
           end;
       end;

 finally
   Stream.Free;
 end;
end;
于 2019-07-16T05:30:19.137 回答