【问题标题】:DBImage with bitmap?DBImage 与位图?
【发布时间】:2012-07-18 11:32:22
【问题描述】:

我目前正在尝试从具有 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;

【问题讨论】:

    标签: delphi delphi-7 tadotable


    【解决方案1】:

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

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

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

    http://support.microsoft.com/kb/205635/en-us - 这显示了一个 sn-p 如何从 OLE 文件中保存文件。

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

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

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

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

    作为简历:

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

    【讨论】:

    • 老实说,我真的不知道你在说什么。当我使用原始问题中所述的代码时,我遇到了访问冲突。我需要做一些具体的事情吗,因为听起来这只是我将图像分配给数据库字段所要做的。我想这有那么难吗?
    • 如果你想成为程序员 - 你必须有一个线索。没有“形象”,这可能是该领域的一些乡巴佬所说的。有一定的数据结构。 Delphi 有自己的,Acces 有自己的,OLe 有自己的,等等。您应该通过它们传递和转换数据结构。 TButton 是一个按钮,TBitBtn 是一个按钮,TSpeedButton 是一个按钮......但它们是不同的按钮。 TBitmap、TImage、TGraphic——这些都是图片。但不同的图片。因此,您应该训练自己了解每个名称背后的数据结构。如果你不知道 - 你就扔
    • 随机骰子。随机访问内存正是访问冲突。你明白了。你很幸运你知道它,它可能会更糟:没有可见的错误,但你的程序只是默默地破坏了数据库。作为程序员,你应该像猫一样古玩,像老人一样迂腐。在同一时间。你必须学会​​查找信息并阅读它。就像 SmartQuestionsFAQ 中所说的那样。所以开始一步一步做。我不会说你应该学习汇编程序(虽然它有助于捕捉编译器错误而不是编写缓慢的愚蠢代码)但是你应该了解每个运行步骤中的每个数据结构是什么
    • 所以请阅读 Delphi Foundations 这样的好书。拿 Delphi Help(它在 Delphi 5 中相当好,它在 XE2 中有点帮助,在 D2006 中很糟糕。没有人知道你的版本。但是拿着它,关于每个学期,训练自己阅读这个数据结构提供的内容以及什么它期待你。
    • 然后采取上述1-2-3个步骤并尝试执行它们。相继。就像乐高一样。找到匹配的立方体并以它们可以连接的方式连接它们。并使他的整个结构足够小而坚固,不会分崩离析。执行第 1 步。
    猜你喜欢
    • 1970-01-01
    • 2012-01-15
    • 2014-09-13
    • 2010-10-31
    • 1970-01-01
    • 2017-02-16
    • 1970-01-01
    • 2015-04-09
    • 1970-01-01
    相关资源
    最近更新 更多