0

我目前正在尝试从具有 OLE 对象字段并包含有效位图的 MS Access 数据库中读取图像(出于测试目的,我使用 MS Paint 创建了图像并将其保存为 24 位 bmp)。

我通过 DBGrid 链接到这个。从理论上讲,一切都应该正常工作并且应该显示图像,但是我得到一个:“位图图像无效”错误。如果这是 JPEG 而不是 .bmp,我可以理解,但事实并非如此。所以我的问题是,有什么问题?

我不一定必须使用 DBImage,普通的 TImage 也可以很好(甚至可能更可取),但我不确定如何将 TImage 分配给 MS Access 数据库中的 OLE 对象字段。我试过了,无济于事:

//Select photo from Image field  
Image1.Picture := ADOTable1['Image'];

我已经阅读了关于这个问题的大部分文章,例如 about.com 等,但仍然没有得到任何好的结果。

任何帮助将不胜感激!

更新:这对我有用:

添加到USES子句:JPEG、ADODB、DB

function JpegStartsInBlob
(PicField:TBlobField):integer;
var
 bS     : TADOBlobStream;
 buffer : Word;
 hx     : string;
begin
 Result := -1;
 bS := TADOBlobStream.Create(PicField, bmRead);
 try
 while (Result = -1) and
    (bS.Position + 1 < bS.Size) do
 begin
  bS.ReadBuffer(buffer, 1);
  hx:=IntToHex(buffer, 2);
  if hx = 'FF' then begin
  bS.ReadBuffer(buffer, 1);
  hx:=IntToHex(buffer, 2);
  if hx = 'D8' then Result := bS.Position - 2
  else if hx = 'FF' then
    bS.Position := bS.Position-1;
end; 
end; 
finally
bS.Free
end;  
end;

procedure TfrmOne.btnShowImageClick(Sender: TObject);
var
 bS : TADOBlobStream;
 Pic : TJPEGImage;
begin

bS := TADOBlobStream.Create(table1.FieldByName('Photo') as TBlobField, bmRead);   
bS.Seek(JpegStartsInBlob(table1.FieldByName('Photo') as TBlobField),
        soFromBeginning);
Pic := TJPEGImage.Create;
Pic.LoadFromStream(bS);
frmOne.Image1.Picture.Graphic := Pic;
Pic.Free;
bS.Free;
end;
4

1 回答 1

0

什么会返回 ADOTable1['Image'] ?

我不喜欢你使用的 FieldValues 属性,因为你不知道实际类型并且无法使用类型检查来控制事物。我想你最好使用 Data.DB.TDataSet.FieldByName TField 对象的类型会提示你它包含的数据类型。

我不了解 Microsoft Jet(Excel 和 Access 的数据库引擎),但我认为它存储原始 BMP 文件数据和一些指向 Paint 应用程序(或 Gimp、Photoshop 或任何用于编辑 BMP 的工具)的链接 Kinf of TBlobField i思考。

http://support.microsoft.com/kb/205635/en-us - 这显示了如何从 OLE 文件中保存文件的片段。

尝试找到一种将字段内容保存到 TFileStream 中的方法。

检查创建的文件是否真的是 BMP 文件。之后将 blob 保存到 TMemoryStream 和 TBitmap.LoadFromStream

考虑 Data.DB.TBlobField.SaveToStream、Data.DB.TField.AsBytes

文档中的另一个片段 - 如果您可以使用这些类,请探索这些类“使用 TADOBlobStream 访问或修改 ADO 数据集中的 BLOB 或备注字段的值。BLOB 字段由 TBlobField 对象和 TBlobField 的后代表示,例如 TGraphicField 和 TMemoField 。”

作为简历:

1) 获取数据的类型 - ADOTable1.FieldByName.ClassName 了解一下,哪些方法属性可以让你获取数据 2) 尝试将数据保存到文件中并分析它是什么 3) 尝试将数据保存到流中并重新用于加载图片

于 2012-07-18T13:41:55.593 回答