加载 Jpg/Gif/Bitmap 并转换为 Bitmap

发布于 2024-07-23 11:50:47 字数 156 浏览 4 评论 0原文

我必须从 XML 文件加载图像。 XML 文件中没有关于图像是否为 JPG/GIF/BMP 的信息。 加载图像后,我需要将其转换为位图。

有谁知道如何在不知道实际文件格式的情况下将图像转换为位图? 我正在使用 Delphi 2007/2009

谢谢。

I have to load an image from an XML file. There is no information in the XML file about whether the image is JPG/GIF/BMP. After loading the image, I need to convert it to Bitmap.

Does anyone have any clue how to convert images to Bitmap without knowing the actual file format? I'm using Delphi 2007/2009

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

A君 2024-07-30 11:50:48

Delphi 2009 内置了对 JPEG、BMP、GIF 和 PNG 的支持。

对于早期版本的 Delphi,您可能需要找到 PNG 和 GIF 的第三方实现,但在 Delphi 2009 中,您只需添加 JpegpngimageGIFImg 单位到您的使用子句中。

如果文件具有扩展名,您可以使用以下代码,正如其他人所指出的,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;

Delphi 2009 comes with built in support for JPEG, BMP, GIF and PNG.

For earlier versions of Delphi you may need to find third party implementations for PNG and GIF, but in Delphi 2009 you simply add the Jpeg, pngimage and GIFImg units to your uses clause.

If the file has an extension you can use the following code, as noted by others the TPicture.LoadFromFile looks at the extensions registered by the inherited classes to determine which image to load.

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;

If the file extension is not known one method is to look at the first few bytes to determine the image type.

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;
茶色山野 2024-07-30 11:50:48

我找到了更简单的方法! 它自动加载 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;

I've found a simpler way! It loads JPG/GIF/BMP etc. files automatically without even knowing/checking the file format, and convert that accordingly. It worked for me perfectly.

Sharing it here :)

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;
梦行七里 2024-07-30 11:50:48

如果您不知道图形的格式,则不能使用 TPicture.LoadFromFile,因为此方法使用文件扩展名来确定需要加载哪种已注册的图形格式。 没有匹配的 TPicture.LoadFromStream 方法是有原因的。

可以在运行时检查数据并确定图形格式的外部库将是最好的解决方案。 您可以使用efg 页面作为您研究的起点。

一种快速而肮脏的解决方案是尝试您需要处理的几种格式,直到成功:

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 库 有一个用于

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

确定图形格式的示例 convert。 这看起来与您提到的 VB6 执行此操作的方式非常相似。 也许您可以使用这个库来达到您的目的。

You can't use TPicture.LoadFromFile if you don't know what format the graphic has, as this method uses the file extension to determine which of the registered graphic formats needs to be loaded. There's a reason that there is no matching TPicture.LoadFromStream method.

An external library which can examine data and determine the graphic format at runtime would be the best solution. You could use the efg page as a starting point of your research.

A quick and dirty solution is to try the few formats you need to handle until one succeeds:

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:

The GraphicEx library has an example convert that uses

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

to determine the graphic format. This seems very similar to the VB6 way of doing this that you mention. Maybe you can use this library for your purpose.

浅紫色的梦幻 2024-07-30 11:50:48

我没有 Delphi 2007 或 2009 来看看这是否适用于这些版本。 然而,在 XE2 中,Vcl.Graphics 中还有一个名为 TWICImage 的类,它处理 Microsoft Imaging Component 支持的图像,包括 BMP、GIF、ICO、JPEG、PNG、TIF 和 Windows Media 照片。 它能够从流中检测图像类型。 假设您在名为 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即可工作>JPEG 添加到您的 uses 语句中。

其他答案显示了如何将 TImage 转换为 BMP,因此我不在此介绍。 我只是展示另一种将各种图形类型加载到 TImage 中的方法,而无需事先知道图像类型或文件扩展名......

I don't have Delphi 2007 or 2009 to see if this will work in either of those versions. However, in XE2, there is another class in Vcl.Graphics called TWICImage that handles images supported by the Microsoft Imaging Component, including BMP, GIF, ICO, JPEG, PNG, TIF and Windows Media Photo. It is capable of detecting the image type from a stream. Assuming you have a TImage on the form called 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;

It works without adding PNGImage, GIFImg, or JPEG to your uses statement.

The other answers show how to convert the TImage to a BMP, so I'm not including that here. I'm just showing another way to load various graphic types into a TImage without knowing beforehand the image type, or the file extension...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文