如何使用 FireDAC 将 Firebird 数据库中的图像作为 Blob 加载到 Delphi 中的 TImage?

How to load an image from Firebird Database as Blob to TImage in Delphi with FireDAC?

我在网上找了很多地方都没有找到合适的解决办法。大多数示例使用其他组件或旨在直接保存等

我的问题是;我在服务器上有 2 个数据库,一个是保存产品信息(股票代码、名称、价格等),另一个是产品图像(可以是 jpeg、png、gif)。两个数据库都有一个唯一的值来配对产品和图像 (prod_id)。

我在表单上放置了 2 个 TFDConnection、2 个 TFDQuery 和 1 个 TDataSource 组件,我从信息数据库中获取数据并通过 TDataSource、TFDConnection、TFDQuery 和其他 TFDConnection 和 TFDQuery 组件将这些数据加载到 StringGrid 中以进行连接图像数据库。

而且我愿意这样做;当我单击 StringGrid 上的一行时,让程序获取所选行的 prod_id 值(直到那里没有问题),然后在图像数据库中搜索是否存在 prod_id 值和图像作为 blob(FILEDATA 字段) ) 在 TImage 控件上显示此图像。

有什么方法可以用 FireDAC 组件做到这一点吗?还是我应该采用另一种方式?谢谢

如果您查看 Delphi 示例文件夹,您应该在 LiveBindings 文件夹下找到一个名为 BindGridLinkVCLProject 的示例(也许您已经在使用它)。

这展示了如何使用实时绑定从 TDataSet 填充 StringGrid 以及如何使用它加载存储在数据库中的图像,基于当前记录显示在StringGrid.

它使用 ClientDataSet 加载了标准 (Borland) Biolife 数据库(又名 FishFacts)的数据。我已经检查过,您可以用 FireDAC 替换 ClientDataSet(我使用 TFDMemTable,因为示例数据也包含其格式的 Biolife DB)。正如 Ken White 在评论中所说,使用 Firebird 数据库应该没有任何区别(当然,除了你使用的 FireDAC 数据集类型)。

我还检查过您是否可以使用第二个 FireDAC 数据集进行查找以检索图像并将其加载到 TImage 中。以下显示如何。

在BindGridLinkVCLProject演示工程中,数据的Graphic列包含 鱼的图片,这通过 Livebinding 显示在 TImage 中。

调整此演示项目以从不同的 TDataSet 检索图像很容易 (尽管在我下面的描述中,我们只是使用了 Biolife 数据集的第二个副本) 并使用 FireDAC 数据集而不是 ClientDataSets。 (显然这是一个人为的例子,因为 Biolife 数据中已经有图像数据,但下面是为了说明即使使用实时绑定,如果需要,也很容易从另一个数据集中检索图像。)

尝试以下操作:

  • 复制项目及其 GridLinkFormUit1.Pas 文件。

  • ClientDataSet1替换为FDMemTable

  • DataSource1BindSourceDB1FDMemTable1

  • 从Biolife.Fds加载FDMemTable1(在IDE中右击它) 示例数据文件夹中的文件。

此时,StringGridWithBindColumns 应显示 Biolife 数据,ImageWithHandler TImage 应显示当前鱼的图片。现在,

  • 双击 BindingList1,然后在弹出窗口中删除 ImageWithHandler 的绑定组件。我们将把它添加到下面的一个单独的 BindingList 中。

  • 向表单添加第二个 FDMemTable 并加载与 FDMemTable1.

  • 相同的数据
  • 在表格中添加第二个 DataSourceBindingList。点 DataSource2FDMemTable2.

  • 然后,双击BindingList2,使用编辑器在两者之​​间添加一个新的绑定 FDMemTable2Graphic 字段和 ImageWithHandler TImage(参见下面的 DFM 如何连接它。绑定编辑器应该自动创建 BindSourceDB2 并且您需要将其 DataSetDataSource 属性设置为 FDMemTable2DataSource2.

然后,将以下代码添加到窗体的单元中,编译并运行:

  TGridLinkForm1 = class(TForm)
    [...]
  public
    { Public declarations }
    DataFileName : String;
  end;


procedure TGridLinkForm1.FormCreate(Sender: TObject);
begin
  DataFileName := 'D:\xe8\samples\Data\Biolife.Fds';
  if not FDMemTable2.Active then
    FDMemTable2.LoadFromFile(DataFileName);
  if not FDMemTable1.Active then
    FDMemTable1.LoadFromFile(DataFileName);
end;

procedure TGridLinkForm1.FDMemTable1AfterScroll(DataSet: TDataSet);
var
  SpeciesNo : Double;
begin
  SpeciesNo := FDMemTable1.FieldByName('Species No').AsFloat;
  if not FDMemTable2.Locate('Species No', SpeciesNo, []) then
    raise Exception.CreateFmt('SpeciesNo %n not found in %s', [SpeciesNo, FDMemTable2.Name]);
end;

DFM 提取:

  object FDMemTable2: TFDMemTable
    FetchOptions.AssignedValues = [evMode]
    FetchOptions.Mode = fmAll
    ResourceOptions.AssignedValues = [rvPersistent, rvSilentMode]
    ResourceOptions.Persistent = True
    ResourceOptions.SilentMode = True
    UpdateOptions.AssignedValues = [uvCheckRequired]
    UpdateOptions.CheckRequired = False
    Left = 24
    Top = 392
  end
  object DataSource2: TDataSource
    DataSet = FDMemTable2
    Left = 88
    Top = 392
  end
  object BindSourceDB2: TBindSourceDB
    DataSource = DataSource2
    ScopeMappings = <>
    Left = 236
    Top = 392
  end
  object BindingsList2: TBindingsList
    Methods = <>
    OutputConverters = <>
    Left = 152
    Top = 392
    object LinkControlToField1: TLinkControlToField
      Category = 'Quick Bindings'
      DataSource = BindSourceDB2
      FieldName = 'Graphic'
      Control = ImageWithHandler
      Track = False
    end
  end