如何将任意图像从BLOB流加载到TImage中?

问题描述:

如果我理解正确,TImage.LoadFromFile将根据文件扩展名确定图片的类型。如何将任意图像从BLOB流加载到TImage中?

有没有什么办法从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 

查看此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; 
.... 
+0

如果你想TSynPicture加载GIF/PNG/JPG/TIFF图像,请在SynGdiPlus.pas的源代码中注释NOTSYNPICTUREREGISTER的定义。 – 2014-04-16 09:10:05

从这里开始,你可以很容易地做到这一点:http://delphihaven.wordpress.com/2011/01/22/tip-detecting-graphic-formats/

事实上,它是TPicture.LoadFromFile检测文件类型,它只是使用的文件扩展名。所以你需要读取流的头部来检测文件类型。另一方面,如果您知道将BLOB放入数据库时​​的格式是什么,您可以始终将该信息作为您自己的BLOB专用标题包含在内。

+2

“读数据流首部”和有克里斯Rolliston博客文章解决问题:) – RBA 2011-06-06 11:51:06

看似魔法 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); 
+0

...所以它从DFM流中读取相应的TPicture类名,而不是使用图片二进制头。所以你不能混合实例Jpeg加载库,或者你必须命名所有实现'TJpegImage'(这就是我为* SynGdiPlus *所做的与用户代码和DFM中的标准'Jpeg'单元兼容加载)。 – 2011-06-06 14:44:30