20 Stimmen

Jpg/Gif/Bitmap laden und in Bitmap konvertieren

Ich muss ein Bild aus einer XML-Datei laden. Die XML-Datei enthält keine Informationen darüber, ob es sich um ein JPG/GIF/BMP-Bild handelt. Nach dem Laden des Bildes muss ich es in ein Bitmap konvertieren.

Hat jemand eine Idee, wie man Bilder in Bitmap konvertieren kann, ohne das eigentliche Dateiformat zu kennen? Ich verwende Delphi 2007/2009

Ich danke Ihnen.

41voto

Kevin Newman Punkte 2357

Delphi 2009 verfügt über eine integrierte Unterstützung für JPEG, BMP, GIF und PNG.

Für frühere Versionen von Delphi müssen Sie möglicherweise Implementierungen von Drittanbietern für PNG und GIF finden, aber in Delphi 2009 fügen Sie einfach die Jpeg , pngimage y GIFImg Einheiten zu Ihrer Verwendungs-Klausel.

Wenn die Datei eine Erweiterung hat, können Sie den folgenden Code verwenden. Wie bereits von anderen erwähnt, prüft TPicture.LoadFromFile die von den geerbten Klassen registrierten Erweiterungen, um das zu ladende Bild zu bestimmen.

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;

Wenn die Dateierweiterung nicht bekannt ist, besteht eine Methode darin, anhand der ersten Bytes den Bildtyp zu bestimmen.

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;

13voto

J K Kunil Punkte 541

Ich habe einen einfacheren Weg gefunden! Es lädt JPG/GIF/BMP usw. Dateien automatisch, ohne das Dateiformat zu kennen/zu überprüfen, und konvertiert sie entsprechend. Bei mir hat es perfekt funktioniert.

Teilen Sie es hier :)

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;

9voto

mghie Punkte 31618

Sie können nicht verwenden TPicture.LoadFromFile wenn Sie nicht wissen, welches Format die Grafik hat, da diese Methode anhand der Dateierweiterung bestimmt, welches der registrierten Grafikformate geladen werden muss. Es gibt einen Grund dafür, dass es keine passende TPicture.LoadFromStream méthode.

Eine externe Bibliothek, die Daten untersuchen und das Grafikformat zur Laufzeit bestimmen kann, wäre die beste Lösung. Sie könnten die efg-Seite als Ausgangspunkt für Ihre Recherche.

Eine schnelle und schmutzige Lösung besteht darin, die verschiedenen Formate auszuprobieren, bis eines davon erfolgreich ist:

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;

Bearbeiten:

El GraphicEx-Bibliothek hat ein Beispiel konvertieren die die

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

um das Grafikformat zu bestimmen. Dies scheint der von Ihnen erwähnten VB6-Methode sehr ähnlich zu sein. Vielleicht können Sie diese Bibliothek für Ihren Zweck verwenden.

7voto

James L. Punkte 9207

Ich habe nicht Delphi 2007 oder 2009, um zu sehen, ob dies in einer dieser Versionen funktionieren wird. In XE2 gibt es jedoch eine weitere Klasse in Vcl.Graphics genannt. TWICImage die Bilder verarbeitet, die von der Microsoft Imaging-Komponente einschließlich BMP, GIF, ICO, JPEG, PNG, TIF und Windows Media Photo . Es ist in der Lage, den Bildtyp aus einem Stream zu erkennen. Angenommen, Sie haben eine TImage auf dem Formular namens Bild1 :

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;

Es funktioniert ohne Zugabe von PNGImage , GIFImg , oder JPEG zu Ihrem uses Erklärung.

Die anderen Antworten zeigen, wie man die TImage in eine BMP-Datei umzuwandeln, weshalb ich sie hier nicht mit aufnehme. Ich zeige nur eine weitere Möglichkeit, verschiedene Grafiktypen in eine TImage ohne vorher den Bildtyp oder die Dateierweiterung zu kennen...

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X