Jam*_* L. 5 delphi image-formats graphics32
我正在使用 Delphi XE2(更新 3)和 GR32。我无法用于TBitmap32.LoadFromStream()加载图像数据。它引发以下异常:
Project MyApp.exe raised exception class EInvalidGraphic with message 'Bitmap image is not valid'.
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
如果我对LoadFromStream()代码进行注释并取消对前两行的注释,它就会起作用——因此它能够在从文件加载图像时确定图像格式。在此示例中,bs包含有效的 PNG 图像。但是,有时它可能是 GIF、JPG、BMP 或其他图形格式。
我也知道我可以使用一个中间对象(例如,TPNGImage,TJPEGImage等),加载使用图像数据LoadFromStream()向中间对象,然后Assign()它向TBitmap32。但是,如果TBitmap32可以在没有中间对象的情况下处理任何类型的图像会更好,我认为它可以......
有谁知道如何使用TBitmap32.LoadFromStream()加载图像并让它自动识别图像格式而不将图像保存到硬盘驱动器(即使是暂时的)或使用中间对象?
Delphi XE2 包含一个Vcl.Graphics名为in 的类,TWICImage用于处理Windows Imaging Component支持的图像,包括BMP、GIF、ICO、JPEG、PNG、TIF 和 Windows Media Photo。这意味着您可以直接从流加载任何支持的图像类型,它会自动检测图像类型并加载它。然后可以将加载的图像分配给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;
Run Code Online (Sandbox Code Playgroud)
它无需在您的语句中添加PNGImage, GIFImg, 或JPEG即可工作uses。
这是代码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;
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,代码检查文件是否是 Windows 位图。如果是这样,那么它会通过调用直接加载它LoadFromStream。
如果没有,则加载到 a 中TPicture,然后分配给该实例。
重点是它LoadFromStream只能理解 Windows 位图。它不理解任何其他文件格式。并且您正在尝试加载 PNG。因此,如果不使用中间对象,就无法完成您需要的操作。
您的解决方案是:
TPNGImage对象。LoadFromStream该实例。Assign实例。TBitmap32TPNGImage