我正在使用Delphi XE2(Update 3)和GR32。我无法使用TBitmap32.LoadFromStream()
加载图片数据。它引发了以下异常:
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或其他图形格式。
我也知道我可以使用中间对象(例如TPNGImage
,TJPEGImage
等),使用LoadFromStream()
将图像数据加载到中间对象中,然后{ {1}}它Assign()
。但是,如果TBitmap32
可以处理没有中间对象的任何类型的图像会更好,我认为它可以...
是否有人知道如何使用TBitmap32
加载图片并让其自动识别图像格式而不将图像保存到HDD(即使是暂时的),或者使用中间图像对象
答案 0 :(得分:4)
Delphi XE2在Vcl.Graphics
中包含一个名为TWICImage
的类,用于处理Windows Imaging Component支持的图像,包括 BMP,GIF,ICO,JPEG,PNG,TIF和Windows Media照片即可。这意味着您可以直接从流中加载任何支持的图像类型,它将自动检测图像类型并加载它。然后,可以将加载的图像分配给TBitmap32
组件(或TImage
或TImage32
等。)
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
声明中添加GIFImg
,JPEG
或uses
即可。
答案 1 :(得分:3)
这是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
直接加载它。
如果没有,则加载到TPicture
然后分配给此实例。
关键是LoadFromStream
只能理解Windows位图。它不了解任何其他文件格式。而你正在尝试加载PNG。因此,如果不使用中间对象,就无法做到所需。
您的解决方案是:
TPNGImage
对象。LoadFromStream
。Assign
实例的TBitmap32
实例上调用TPNGImage
。