首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >()自动识别图像格式

()自动识别图像格式
EN

Stack Overflow用户
提问于 2013-06-20 08:27:39
回答 2查看 6.7K关注 0票数 5

我正在使用德尔菲XE2 (更新3)和GR32。我无法使用TBitmap32.LoadFromStream()加载图像数据。它引发以下例外情况:

代码语言:javascript
复制
Project MyApp.exe raised exception class EInvalidGraphic with message 'Bitmap image is not valid'.

代码

代码语言:javascript
复制
uses GR32, GifImg, PngImage, Vcl.Graphics;

var
  pic: TBitmap32;
  bs: TBytesStream;
begin
  bs := TBytesStream.Create(TClientDataSet(cds).FieldByName('filedata').AsBytes);
  try
    pic := TBitmap32.Create;
    try
//      bs.SaveToFile('c:\delme.png');
//      pic.LoadFromFile('c:\delme.png');
      pic.LoadFromStream(bs); // <- EInvalidGraphic exception
      // do something with 'pic'
    finally
      FreeAndNil(pic);
    end;
  finally
    FreeAndNil(bs);
  end;
end;

解决办法

如果我注释LoadFromStream()代码并取消对前两行的注释,它就能工作--因此它能够在从文件中加载图像格式时确定图像格式。在本例中,bs包含一个有效的PNG映像。然而,有时它可能是一个GIF,JPG,BMP或其他图形格式。

我还知道,我可以使用中间对象(例如,TPNGImageTJPEGImage等),使用LoadFromStream()将图像数据加载到中间对象,然后将其加载到TBitmap32。然而,如果TBitmap32可以处理任何类型的图像,而没有中间对象,那就更好了,我认为它可以.

问题

有人知道如何使用TBitmap32.LoadFromStream()加载图像,并让它自动识别图像格式的,而不需要将图像保存到硬盘(甚至是临时的),或者使用中间对象?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-06-20 08:37:46

这是LoadFromFile的代码

代码语言:javascript
复制
procedure TCustomBitmap32.LoadFromFile(const FileName: string);
var
  FileStream: TFileStream;
  Header: TBmpHeader;
  P: TPicture;
begin
  FileStream := TFileStream.Create(Filename, fmOpenRead);
  try
    FileStream.ReadBuffer(Header, SizeOf(TBmpHeader));

    // Check for Windows bitmap magic bytes...
    if Header.bfType = $4D42 then
    begin
      // if it is, use our stream read method...
      FileStream.Seek(-SizeOf(TBmpHeader), soFromCurrent);
      LoadFromStream(FileStream);
      Exit;
    end
  finally
    FileStream.Free;
  end;

  // if we got here, use the fallback approach via TPicture...
  P := TPicture.Create;
  try
    P.LoadFromFile(FileName);
    Assign(P);
  finally
    P.Free;
  end;
end;

如您所见,代码检查该文件是否为Windows位图。如果是,那么它将通过调用LoadFromStream直接加载它。

如果不是,那么它将加载到一个TPicture中,然后分配给这个实例。

关键是LoadFromStream只理解Windows位图。它不理解任何其他文件格式。你正在尝试装载一个PNG。因此,如果不使用中间对象,就无法完成所需的任务。

你的解决办法是:

  1. 实例化TPNGImage对象。
  2. 在该实例上调用LoadFromStream
  3. 在传递Assign实例的TBitmap32实例上调用TPNGImage
票数 3
EN

Stack Overflow用户

发布于 2013-11-19 23:55:29

Delphi XE2在Vcl.Graphics中包含一个名为TWICImage的类,它处理http://msdn.microsoft.com/en-us/library/windows/desktop/ee719654%28v=vs.85%29.aspx支持的图像,包括BMP、GIF、ICO、JPEG、PNG、TIF和Windows 。这意味着您可以直接从流加载任何受支持的图像类型,并且它将自动检测图像类型并加载它。然后,可以将加载的映像分配给TBitmap32组件(或TImageTImage32等)。

代码语言:javascript
复制
uses GR32, Vcl.Graphics;

var
  pic: TBitmap32;
  wic: TWICImage;
  bs: TBytesStream;
begin
  bs := TBytesStream.Create(TClientDataSet(cds).FieldByName('filedata').AsBytes);
  try
    pic := TBitmap32.Create;
    try
      wic := TWICImage.Create;
      try
        bs.Position := 0;
        wic.LoadFromStream(bs);
        pic.Assign(wic);
      finally
        FreeAndNil(wic);
      end;
    finally
      FreeAndNil(pic);
    end;
  finally
    FreeAndNil(bs);
  end;
end;

它在不向您的PNGImage语句中添加GIFImgJPEG的情况下工作。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17208785

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档