Загрузите Jpg / Gif / Bitmap и конвертируйте в Bitmap - PullRequest
16 голосов
/ 06 июня 2009

Мне нужно загрузить изображение из файла XML. В файле XML нет информации о том, является ли изображение JPG / GIF / BMP. После загрузки изображения мне нужно преобразовать его в растровое изображение.

Кто-нибудь знает, как конвертировать изображения в растровое изображение, не зная фактического формата файла? Я пользуюсь Delphi 2007/2009

Спасибо.

Ответы [ 4 ]

33 голосов
/ 06 июня 2009

Delphi 2009 поставляется со встроенной поддержкой JPEG, BMP, GIF и PNG.

Для более ранних версий Delphi вам может понадобиться найти сторонние реализации для PNG и GIF, но в Delphi 2009 вы просто добавляете единицы Jpeg, pngimage и GIFImg к предложению использования.

Если файл имеет расширение, вы можете использовать следующий код, как отмечали другие, 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;
14 голосов
/ 07 июня 2009

Я нашел более простой способ! Он автоматически загружает файлы 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;
9 голосов
/ 06 июня 2009

Нельзя использовать 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;

Изменить:

В библиотеке GraphicEx есть пример convert , использующий

GraphicClass := FileFormatList.GraphicFromContent(...);

для определения графического формата. Это кажется очень похожим на способ VB6, который вы упоминаете. Может быть, вы можете использовать эту библиотеку для своих целей.

6 голосов
/ 20 ноября 2013

У меня нет Delphi 2007 или 2009, чтобы посмотреть, будет ли это работать в любой из этих версий. Однако в XE2 есть еще один класс в Vcl.Graphics, называемый TWICImage, который обрабатывает изображения, поддерживаемые Microsoft Imaging Component , включая BMP, GIF, ICO, JPEG, PNG, TIF и Windows Медиа-фото . Он способен обнаруживать тип изображения из потока. Предположим, у вас есть 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, не зная заранее тип изображения или расширение файла ...

...