web-dev-qa-db-ja.com

Jpg / Gif /ビットマップをロードしてビットマップに変換する

XMLファイルから画像を読み込む必要があります。 XMLファイルには、画像がJPG/GIF/BMPであるかどうかに関する情報はありません。画像を読み込んだ後、ビットマップに変換する必要があります。

実際のファイル形式を知らずに画像をビットマップに変換する方法を知る手がかりはありますか? Delphi 2007/2009を使用しています

ありがとうございました。

17
J K Kunil

もっと簡単な方法を見つけました!それは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;
14
J K Kunil

Delphi 2009には、JPEG、BMP、GIF、PNGのサポートが組み込まれています。

Delphiの以前のバージョンでは、PNGおよびGIFのサードパーティ実装を見つける必要がある場合がありますが、Delphi 2009では、Jpegpngimageおよび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;
36
Kevin Newman

このメソッドはファイル拡張子を使用して、どの登録済みグラフィック形式をロードする必要があるかを決定するため、グラフィックの形式がわからない場合は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がこれを行う方法と非常によく似ています。多分あなたはあなたの目的のためにこのライブラリを使用することができます。

9
mghie

Delphi 2007または2009で、これらがどちらのバージョンでも機能するかどうかを確認できません。ただし、XE2では、Vcl.GraphicsTWICImageと呼ばれる別のクラスがあり、Microsoft Imaging Componentがサポートするイメージを処理します。 BMP、GIF、ICO、JPEG、PNG、TIFおよびWindows Media Photoを含みます。ストリームから画像タイプを検出できます。 Image1というフォームにTImageがあると仮定します。

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;

PNGImageGIFImg、またはJPEGusesステートメントに追加しなくても機能します。

他の回答はTImageをBMPに変換する方法を示しているので、ここでは省略します。画像のタイプやファイル拡張子を事前に知らなくても、さまざまなグラフィックタイプをTImageにロードする別の方法を示しています...

6
James L.