web-dev-qa-db-fra.com

Charger Jpg / Gif / Bitmap et convertir en Bitmap

Je dois charger une image à partir d'un fichier XML. Le fichier XML ne contient aucune information indiquant si l'image est au format JPG/GIF/BMP. Après avoir chargé l'image, je dois la convertir en Bitmap.

Quelqu'un sait-il comment convertir des images en Bitmap sans connaître le format de fichier réel? J'utilise Delphi 2007/2009

Je vous remercie.

17
J K Kunil

J'ai trouvé un moyen plus simple! Il charge automatiquement les fichiers JPG/GIF/BMP, etc. sans même connaître/vérifier le format de fichier, et les convertir en conséquence. Cela a parfaitement fonctionné pour moi.

Partager ici :)

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;
14
J K Kunil

Delphi 2009 est livré avec un support intégré pour JPEG, BMP, GIF et PNG.

Pour les versions antérieures de Delphi, vous devrez peut-être trouver des implémentations tierces pour PNG et GIF, mais dans Delphi 2009, vous ajoutez simplement les unités Jpeg, pngimage et GIFImg à vos utilisations. clause.

Si le fichier a une extension, vous pouvez utiliser le code suivant, comme indiqué par d'autres, TPicture.LoadFromFile examine les extensions enregistrées par les classes héritées pour déterminer l'image à charger.

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;

Si l'extension de fichier n'est pas connue, une méthode consiste à examiner les premiers octets pour déterminer le type d'image.

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;
36
Kevin Newman

Vous ne pouvez pas utiliser TPicture.LoadFromFile si vous ne connaissez pas le format du graphique, car cette méthode utilise l'extension de fichier pour déterminer lequel des formats graphiques enregistrés doit être chargé. Il y a une raison pour laquelle il n'y a pas de correspondance TPicture.LoadFromStream méthode.

Une bibliothèque externe qui peut examiner les données et déterminer le format graphique lors de l'exécution serait la meilleure solution. Vous pouvez utiliser la page efg comme point de départ de votre recherche.

Une solution rapide et sale consiste à essayer les quelques formats que vous devez gérer jusqu'à ce que l'un réussisse:

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;

Modifier:

La bibliothèque GraphicEx a un exemple convert qui utilise

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

pour déterminer le format graphique. Cela semble très similaire à la façon de procéder VB6 que vous mentionnez. Vous pouvez peut-être utiliser cette bibliothèque pour votre but.

9
mghie

Je n'ai pas Delphi 2007 ou 2009 pour voir si cela fonctionnera dans l'une de ces versions. Cependant, dans XE2, il existe une autre classe dans Vcl.Graphics appelé TWICImage qui gère les images prises en charge par le Microsoft Imaging Component , y compris BMP, GIF, ICO, JPEG, PNG, TIF et Windows Media Photo. Il est capable de détecter le type d'image à partir d'un flux. En supposant que vous avez un TImage sur le formulaire appelé 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;

Il fonctionne sans ajouter PNGImage, GIFImg ou JPEG à votre instruction uses.

Les autres réponses montrent comment convertir le TImage en BMP, donc je ne l'inclus pas ici. Je montre juste une autre façon de charger différents types de graphiques dans un TImage sans connaître au préalable le type d'image ou l'extension de fichier ...

6
James L.