TBitmap32.LoadFromStream()自动识别图像格式 [英] TBitmap32.LoadFromStream() Auto-Recognize Image Format

查看:367
本文介绍了TBitmap32.LoadFromStream()自动识别图像格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Delphi XE2(更新3)和GR32.我无法使用TBitmap32.LoadFromStream()加载图像数据.它将引发以下异常:

I'm using Delphi XE2 (Update 3) and GR32. I am unable to use TBitmap32.LoadFromStream() to load the image data. It raises the following exception:

Project MyApp.exe raised exception class EInvalidGraphic with message 'Bitmap image is not valid'.

代码

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或其他图形格式.

Workaround(s)

If I comment the LoadFromStream() code and uncomment the prior two lines, it works -- so it is able to determine the image format when loading it from a file. In this example, bs contains a valid PNG image. However, sometimes it may be a GIF, JPG, BMP or another graphic format.

我也知道我可以使用中间对象(例如TPNGImageTJPEGImage等),使用LoadFromStream()将图像数据加载到中间对象中,然后将Assign()加载到TBitmap32.但是,如果TBitmap32可以在没有中间对象的情况下处理任何类型的图像会更好,我认为这可以...

I also know that I can use an intermediate object (e.g., TPNGImage, TJPEGImage, etc.), load the image data using LoadFromStream() into the intermediate object, and then Assign() it to the TBitmap32. However, it would be better if TBitmap32 could handle any type of image without an intermediate object, which I thought it could...

有人知道如何使用TBitmap32.LoadFromStream()加载图像并使其自动识别图像格式而无需将图像保存到HDD(甚至是临时保存)或使用中间对象吗?

Does anyone know how to use TBitmap32.LoadFromStream() to load the image and have it auto-recognize the image format without saving the image to the HDD (even temporarily), or using an intermediate object?

推荐答案

这是LoadFromFile的代码:

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直接加载它.

As you can see, the code checks to see if the file is a Windows bitmap. If so then it loads it directly by calling LoadFromStream.

如果没有,它将加载到TPicture中,然后分配给该实例.

If not then it loads into a TPicture and then assigns to this instance.

重点是LoadFromStream仅了解Windows位图.它不了解任何其他文件格式.您正在尝试加载PNG.因此,没有中间对象就无法做您需要的事情.

The point is that LoadFromStream only understands Windows bitmaps. It does not understand any other file format. And you are trying to load a PNG. So, there's no way to do what you need without using an intermediate object.

您的解决方案是:

  1. 实例化TPNGImage对象.
  2. 在该实例上调用LoadFromStream.
  3. TBitmap32实例上调用Assign并传递TPNGImage实例.
  1. Instantiate a TPNGImage object.
  2. Call LoadFromStream on that instance.
  3. Call Assign on the TBitmap32 instance passing the TPNGImage instance.

这篇关于TBitmap32.LoadFromStream()自动识别图像格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆