如何使用 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
。
点 DataSource1
和 BindSourceDB1
在 FDMemTable1
。
从Biolife.Fds加载FDMemTable1
(在IDE中右击它)
示例数据文件夹中的文件。
此时,StringGridWithBindColumns
应显示 Biolife 数据,ImageWithHandler
TImage 应显示当前鱼的图片。现在,
双击 BindingList1
,然后在弹出窗口中删除 ImageWithHandler
的绑定组件。我们将把它添加到下面的一个单独的 BindingList 中。
向表单添加第二个 FDMemTable 并加载与 FDMemTable1
.
相同的数据
在表格中添加第二个 DataSource
和 BindingList
。点 DataSource2
于
FDMemTable2
.
然后,双击BindingList2
,使用编辑器在两者之间添加一个新的绑定
FDMemTable2
的 Graphic
字段和 ImageWithHandler
TImage(参见下面的 DFM
如何连接它。绑定编辑器应该自动创建 BindSourceDB2
并且您需要将其 DataSet
和 DataSource
属性设置为 FDMemTable2
和 DataSource2
.
然后,将以下代码添加到窗体的单元中,编译并运行:
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
我在网上找了很多地方都没有找到合适的解决办法。大多数示例使用其他组件或旨在直接保存等
我的问题是;我在服务器上有 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
。点
DataSource1
和BindSourceDB1
在FDMemTable1
。从Biolife.Fds加载
FDMemTable1
(在IDE中右击它) 示例数据文件夹中的文件。
此时,StringGridWithBindColumns
应显示 Biolife 数据,ImageWithHandler
TImage 应显示当前鱼的图片。现在,
双击
BindingList1
,然后在弹出窗口中删除ImageWithHandler
的绑定组件。我们将把它添加到下面的一个单独的 BindingList 中。向表单添加第二个 FDMemTable 并加载与
FDMemTable1
. 相同的数据
在表格中添加第二个
DataSource
和BindingList
。点DataSource2
于FDMemTable2
.然后,双击
BindingList2
,使用编辑器在两者之间添加一个新的绑定FDMemTable2
的Graphic
字段和ImageWithHandler
TImage(参见下面的 DFM 如何连接它。绑定编辑器应该自动创建BindSourceDB2
并且您需要将其DataSet
和DataSource
属性设置为FDMemTable2
和DataSource2
.
然后,将以下代码添加到窗体的单元中,编译并运行:
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