加载Jpg / Gif / Bitmap并转换为Bitmap
image-processing
5
0

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

没有人知道如何将图像转换为位图的任何线索吗?我正在使用Delphi 2007/2009

谢谢。

参考资料:
Stack Overflow
收藏
评论
共 4 个回答
高赞 时间 活跃

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

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

对于较早版本的Delphi,您可能需要找到PNG和GIF的第三方实现,但是在Delphi 2009中,您只需将JpegpngimageGIFImg单位添加到您的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;
收藏
评论

我没有Delphi 2007或2009,看看这是否可以在这些版本中使用。但是,在XE2中, Vcl.Graphics还有另一个类称为TWICImage ,它可以处理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;

它的工作原理无需添加PNGImageGIFImgJPEG到你uses的语句。

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

收藏
评论

如果您不知道图形具有什么格式,则不能使用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(...);

确定图形格式。这似乎与您提到的VB6做到这一点非常相似。也许您可以出于自己的目的使用该库。

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号