【问题标题】:How to load an arbitrary image from a BLOB stream into a TImage?如何将 BLOB 流中的任意图像加载到 TImage 中?
【发布时间】:2011-06-06 11:42:13
【问题描述】:

如果我理解正确,TImage.LoadFromFile 会根据文件扩展名确定图片的类型。

有什么方法可以自动从 TBlobStream 中检测到带有原始图像的图像类型?

我当前的代码:

procedure LoadImageFromStream(AImage: TImage; ADataSet: TDataSet);
var
  Stream: TStream;
begin
  Stream := ADataSet.CreateBlobStream(Field, bmRead);
  try
    AImage.Picture.Graphic.LoadFromStream(Stream);
  finally
    Stream.Free;
  end;
end

【问题讨论】:

    标签: delphi stream delphi-2007 detect timage


    【解决方案1】:

    请参阅此SO answer 以从标题中检索文件内容。

    或者您可以使用我们的TSynPicture class,它将使用 Gdi+ 库在一个类中处理所有类型的图片 (bmp/gif/tiff/jpg/png)。所以你的TPicture 可以是这个独特的类,适用于任何类型的图片。与 Jpeg 或 PNG Delphi 单元相比,代码开销更少。

    var Pic: TSynPicture;
    
    Pic := TSynPicture.Create;
    Pic.LoadFromStream(aStream); // will load bmp/gif/tiff/jpeg/png content
    AImage.Picture.Graphic := Pic;
    ....
    

    【讨论】:

    • 如果想让 TSynPicture 加载 GIF/PNG/JPG/TIFF 图片,请在 SynGdiPlus.pas 的源代码中注释 NOTSYNPICTUREREGISTER 的定义。
    【解决方案2】:

    【讨论】:

      【解决方案3】:

      实际上是TPicture.LoadFromFile 检测文件类型,它只是使用文件扩展名。所以你需要读取流的头部来检测文件类型。

      另一方面,如果您知道将 BLOB 放入数据库时​​的格式是什么,则可以始终将该信息作为您自己的私有标头包含在 BLOB 中。

      【讨论】:

      • "read the header of the stream" 还有 Chris Rolliston 的博文解决了这个问题:)
      【解决方案4】:

      看似魔术 TPicture 对任意图像格式的巧妙处理实际上非常简单(不是说粗略)。从文件加载依赖于文件扩展名。从剪贴板加载 - 在剪贴板格式指示器上。看?总是有格式标签来指示 TPicture 使用哪个 TGraphicClass 来处理数据,而 TGraphic 基类本身除了试错法之外没有提供识别“自己的”数据流的机制。有人可能会好奇 TPicture 如何从 DFM 流中加载自身,但这也不例外,这里是实现的相关摘录(提供版权代码仅用于说明目的):

      procedure TPicture.ReadData(Stream: TStream);
      var
        {...}
        GraphicClass: TGraphicClass;
        LClassName: string;
        LBytes: TBytes;
        LNameLen: Byte;
      begin
        Stream.Read(LNameLen, 1);
        SetLength(LBytes, LNameLen);
        Stream.Read(LBytes{$IFNDEF CLR}[0]{$ENDIF}, LNameLen);
        LClassName := TEncoding.UTF8.GetString(LBytes);
      
        GraphicClass := FileFormats.FindClassName(LClassName);
      

      【讨论】:

      • ... 所以它从 DFM 流中读取相应的 TPicture 类名称,而不是使用 Picture 二进制标头。因此,您不能混合例如 Jpeg 加载库,否则您必须将所有实现命名为 TJpegImage(这就是我为 SynGdiPlus 所做的以与标准 Jpeg 单元兼容在用户代码和 DFM 加载中)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-09
      • 1970-01-01
      • 1970-01-01
      • 2013-02-25
      • 2016-10-29
      • 1970-01-01
      • 2010-11-03
      相关资源
      最近更新 更多