Загрузите Jpg/Gif/Bitmap и конвертируйте в Bitmap
Мне нужно загрузить изображение из файла XML. В файле XML нет информации о том, является ли изображение JPG/GIF/BMP. После загрузки изображения мне нужно преобразовать его в Bitmap.
Кто-нибудь знает, как конвертировать изображения в Bitmap, не зная фактического формата файла? Я использую Delphi 2007/2009
Спасибо.
Ответы
Ответ 1
Я нашел более простой способ! Он автоматически загружает файлы JPG/GIF/BMP и т.д., Даже не зная/не проверяя формат файла и не конвертирует его соответствующим образом. Он отлично работал у меня.
Поделиться здесь:)
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;
Ответ 2
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;
Ответ 3
Вы не можете использовать TPicture.LoadFromFile
, если вы не знаете, какой формат имеет графический файл, так как этот метод использует расширение файла, чтобы определить, какой из зарегистрированных графических форматов необходимо загрузить. Причина в том, что нет подходящего метода TPicture.LoadFromStream
.
Лучшим решением будет внешняя библиотека, которая может проверять данные и определять графический формат во время выполнения. Вы можете использовать efg page как отправную точку своего исследования.
Быстрое и грязное решение - попробовать несколько форматов, которые вам нужно обработать, пока не получится:
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;
Edit:
Библиотека GraphicEx имеет пример преобразования, который использует
GraphicClass := FileFormatList.GraphicFromContent(...);
чтобы определить графический формат. Это похоже на VB6-способ сделать это, о котором вы упоминаете. Возможно, вы можете использовать эту библиотеку для своей цели.
Ответ 4
У меня нет Delphi 2007 или 2009, чтобы увидеть, будет ли это работать в любой из этих версий. Однако в XE2 существует еще один класс в Vcl.Graphics
, называемый TWICImage
, который обрабатывает изображения, поддерживаемые компонентом Microsoft Imaging, включая BMP, GIF, ICO, JPEG, PNG, TIF и Windows Media Photo, Он способен обнаруживать тип изображения из потока. Предполагая, что у вас есть TImage
в форме с именем Image1:
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;
Он работает без добавления PNGImage
, GIFImg
или JPEG
в оператор uses
.
Другие ответы показывают, как преобразовать TImage
в BMP, поэтому я не включаю это здесь. Я просто показываю другой способ загрузки различных графических типов в TImage
, не зная заранее тип изображения или расширение файла...