Delphi 加载Jpg/Gif/位图并转换为位图
我必须从XML文件加载一个图像。XML文件中没有关于图像是否为JPG/GIF/BMP的信息。加载图像后,我需要将其转换为位图 有人知道如何在不知道实际文件格式的情况下将图像转换为位图吗?我使用的是Delphi2007/2009Delphi 加载Jpg/Gif/位图并转换为位图,delphi,image-processing,bitmap,vcl,file-format,Delphi,Image Processing,Bitmap,Vcl,File Format,我必须从XML文件加载一个图像。XML文件中没有关于图像是否为JPG/GIF/BMP的信息。加载图像后,我需要将其转换为位图 有人知道如何在不知道实际文件格式的情况下将图像转换为位图吗?我使用的是Delphi2007/2009 谢谢。Delphi 2009内置了对JPEG、BMP、GIF和PNG的支持 对于早期版本的Delphi,您可能需要找到PNG和GIF的第三方实现,但在Delphi 2009中,您只需将Jpeg、pngimage和GIFImg单位添加到uses子句中即可 如果文件具有扩展名
谢谢。Delphi 2009内置了对JPEG、BMP、GIF和PNG的支持 对于早期版本的Delphi,您可能需要找到PNG和GIF的第三方实现,但在Delphi 2009中,您只需将
Jpeg
、pngimage
和GIFImg
单位添加到uses子句中即可
如果文件具有扩展名,则可以使用以下代码,如其他人所述,TPicture.LoadFromFile会查看继承类注册的扩展名,以确定要加载的图像
uses
Graphics, Jpeg, pngimage, GIFImg;
procedure TForm1.Button1Click(Sender: TObject);
var
Picture: TPicture;
Bitmap: TBitmap;
begin
Picture := TPicture.Create;
try
Picture.LoadFromFile('C:\imagedata.dat');
Bitmap := TBitmap.Create;
try
Bitmap.Width := Picture.Width;
Bitmap.Height := Picture.Height;
Bitmap.Canvas.Draw(0, 0, Picture.Graphic);
Bitmap.SaveToFile('C:\test.bmp');
finally
Bitmap.Free;
end;
finally
Picture.Free;
end;
end;
如果文件扩展名未知,一种方法是查看前几个字节以确定图像类型
procedure DetectImage(const InputFileName: string; BM: TBitmap);
var
FS: TFileStream;
FirstBytes: AnsiString;
Graphic: TGraphic;
begin
Graphic := nil;
FS := TFileStream.Create(InputFileName, fmOpenRead);
try
SetLength(FirstBytes, 8);
FS.Read(FirstBytes[1], 8);
if Copy(FirstBytes, 1, 2) = 'BM' then
begin
Graphic := TBitmap.Create;
end else
if FirstBytes = #137'PNG'#13#10#26#10 then
begin
Graphic := TPngImage.Create;
end else
if Copy(FirstBytes, 1, 3) = 'GIF' then
begin
Graphic := TGIFImage.Create;
end else
if Copy(FirstBytes, 1, 2) = #$FF#$D8 then
begin
Graphic := TJPEGImage.Create;
end;
if Assigned(Graphic) then
begin
try
FS.Seek(0, soFromBeginning);
Graphic.LoadFromStream(FS);
BM.Assign(Graphic);
except
end;
Graphic.Free;
end;
finally
FS.Free;
end;
end;
如果不知道图形的格式,则不能使用
TPicture.LoadFromFile
,因为此方法使用文件扩展名来确定需要加载哪些已注册的图形格式。原因是没有匹配的TPicture.LoadFromStream
方法
一个可以在运行时检查数据并确定图形格式的外部库是最好的解决方案。你可以把这个实验作为你研究的起点
一个快速而肮脏的解决方案是尝试几种需要处理的格式,直到成功:
function TryLoadPicture(const AFileName: string; APicture: TPicture): boolean;
const
GraphicClasses: array[0..3] of TGraphicClass = (
TBitmap, TJPEGImage, TGIFImage, TPngImage);
var
FileStr, MemStr: TStream;
ClassIndex: integer;
Graphic: TGraphic;
begin
Assert(APicture <> nil);
FileStr := TFileStream.Create('D:\Temp\img.dat', fmOpenRead);
try
MemStr := TMemoryStream.Create;
try
MemStr.CopyFrom(FileStr, FileStr.Size);
// try various
for ClassIndex := Low(GraphicClasses) to High(GraphicClasses) do begin
Graphic := GraphicClasses[ClassIndex].Create;
try
try
MemStr.Seek(0, soFromBeginning);
Graphic.LoadFromStream(MemStr);
APicture.Assign(Graphic);
Result := TRUE;
exit;
except
end;
finally
Graphic.Free;
end;
end;
finally
MemStr.Free;
end;
finally
FileStr.Free;
end;
Result := FALSE;
end;
确定图形格式。这似乎与您提到的VB6方法非常相似。也许你可以将这个库用于你的目的。我找到了一个更简单的方法!它自动加载JPG/GIF/BMP等文件,甚至不知道/检查文件格式,并相应地进行转换。它对我非常有效 在此处共享:)
我没有Delphi2007或2009来查看这两个版本是否都能正常工作。但是,在XE2中,
Vcl.Graphics
中有另一个类称为TWICImage
,它处理Microsoft图像组件支持的图像,包括BMP、GIF、ICO、JPEG、PNG、TIF和Windows Media Photo。它能够从流中检测图像类型。假设您在名为Image1的表单上有一个TImage
:
它不需要在uses
语句中添加PNGImage
、GIFImg
或JPEG
其他答案显示了如何将
TImage
转换为BMP,因此我这里不包括它。我只是展示了另一种将各种图形类型加载到TImage
中的方法,而事先不知道图像类型或文件扩展名…这很简单吗?非常感谢你!是的,图像数据位于xml文件的CDATA部分。顺便说一句,Delphi2007不支持Gif吗?我不需要png支持。Jpeg已经存在一段时间了。我不太清楚。我过去一直使用Jedi来支持GIF。用法:fmOpenRead或fmsharedynone{这可以防止文件锁定时失败}感谢您的解决方案并澄清了上述响应。您的代码看起来很有趣,但正如您所提到的,它实际上是一种快速而肮脏的方法。我正在寻找类似于VB 6 LoadPicture的函数,该函数适用于受支持的图像,而不考虑文件扩展名。引用GraphicEx网站的话:“上次更改:2007年2月3日”在C++Builder Xe5中工作得非常好TPicture::Assign
是否将图像数据复制到图像中?(我担心wic.Free
)之后会出现悬空指针@MattMcNabb-是的,它会复制它(),这是通过VCL代码跟踪验证的。通过wic加载比通过TImage加载文件快得多。是的。悲哀的没有PNG=没有乐趣!请注意,这个答案有严重的内存管理错误。如果TOleGraphic
构造函数失败,您将在随机指针上尝试fs.Free
、OleGraphic.Free
、Source.Free
和bmp.Free
,这是非常糟糕的!类似地,如果TFileStream
构造函数失败,您将尝试对随机指针执行fs.Free
、Source.Free
和bmp.Free
。依此类推,直到bmp.Width:=…
。这一行是正确的第一行。始终使用成语X:=TX.Create;尝试{use X}最后X.Free;结束
,或者至少在尝试之前初始化指向nil
的指针。在解决此问题之前,我将执行-1。另请参见:
GraphicClass := FileFormatList.GraphicFromContent(...);
Uses
Classes, ExtCtrls, Graphics, axCtrls;
Procedure TForm1.Button1Click(Sender: TObject);
Var
OleGraphic : TOleGraphic;
fs : TFileStream;
Source : TImage;
BMP : TBitmap;
Begin
Try
OleGraphic := TOleGraphic.Create; {The magic class!}
fs := TFileStream.Create('c:\testjpg.dat', fmOpenRead Or fmSharedenyNone);
OleGraphic.LoadFromStream(fs);
Source := Timage.Create(Nil);
Source.Picture.Assign(OleGraphic);
BMP := TBitmap.Create; {Converting to Bitmap}
bmp.Width := Source.Picture.Width;
bmp.Height := source.Picture.Height;
bmp.Canvas.Draw(0, 0, source.Picture.Graphic);
image1.Picture.Bitmap := bmp; {Show the bitmap on form}
Finally
fs.Free;
OleGraphic.Free;
Source.Free;
bmp.Free;
End;
End;
procedure LoadImageFromStream(Stream: TStream; Image: TImage);
var
wic: TWICImage;
begin
Stream.Position := 0;
wic := TWICImage.Create;
try
wic.LoadFromStream(Stream);
Image.Picture.Assign(wic);
finally
wic.Free;
end;
end;
procedure RenderImage(const Filename: string);
var
fs: TFileStream;
begin
fs := TFileStream.Create(Filename, fmOpenRead);
try
LoadImageFromStream(fs, Image1);
finally
fs.Free;
end;
end;