TBitmap32.LoadFromStream()自动识别图像格式 [英] TBitmap32.LoadFromStream() Auto-Recognize Image Format
问题描述
我正在使用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.
我也知道我可以使用中间对象(例如TPNGImage
,TJPEGImage
等),使用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.
您的解决方案是:
- 实例化
TPNGImage
对象. - 在该实例上调用
LoadFromStream
. - 在
TBitmap32
实例上调用Assign
并传递TPNGImage
实例.
- Instantiate a
TPNGImage
object. - Call
LoadFromStream
on that instance. - Call
Assign
on theTBitmap32
instance passing theTPNGImage
instance.
这篇关于TBitmap32.LoadFromStream()自动识别图像格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!