首页 > 解决方案 > Jpeg 到 Bmp 的转换需要不合理的时间

问题描述

我有这个功能需要 4.2 秒才能将 jpg 转换为 bmp。为什么需要这么长时间?如果更快,我可以吗?
IrfanView 加载和转换文件的时间只是其中的一小部分。

我认为大部分时间都花在 JPG.LoadFromFile 中。但是当我测量时间时,我惊讶地发现它大部分时间都花在了 BMP.Assing(JPG) 上。

function ConvertJPG2BMP(CONST FileName: string): TBitmap;
VAR JPG: TJpegImage;
begin
 Result:= NIL;
 JPG:= TJpegImage.Create;
 TRY
   JPG.LoadFromFile(FileName);
   if  (JPG.Width > 0) AND (JPG.Width  < 32768)
   AND (JPG.Height> 0) AND (JPG.Height < 32768) then
    begin
      Result:= TBitmap.Create;
      TRY
        Result.HandleType:= bmDIB;

        // Fuji_FinePix_F550.JPG    [3200x1800] [1.44MB] 
        Result.Assign(JPG);  <--- 4 seconds!!
      EXCEPT
        FreeAndNil(Result);
      END;
    end;
 FINALLY
   FreeAndNil(JPG);
 end;
end;

标签: delphi

解决方案


由于我想测试一次稍微旧的功能,现在是一个很好的机会。

使用的来源在这里

这些已经在下面的代码中进行了一些更改。

OP的一些改编的源代码function ConvertJPG2BMP()(2512:ms)

在此处输入图像描述

function ConvertJPG2BMP(CONST FileName: string): TBitmap;
VAR
 JPG: TJpegImage;
begin
 Result:= NIL;
 JPG:= TJpegImage.Create;
 TRY
   JPG.LoadFromFile(FileName);
   if  (JPG.Width > 0) AND (JPG.Width  < 32768)
   AND (JPG.Height> 0) AND (JPG.Height < 32768) then
    begin
      Result:= TBitmap.Create;
      TRY
        Result.PixelFormat := pf24bit;
        Result.Width  := JPG.Width;
        Result.Height := JPG.Height;
        Result.HandleType:= bmDIB;
        // 2018-10-17 14.04.23.jpg    [2560x1920] [1.66MB]
        Result.Assign(JPG); 
        Result.SaveToFile('F:\ProgramFiles\Embarcadero\dtx\Projects\Bmp-DIB\JPG2BMP.bmp');
      EXCEPT
        FreeAndNil(Result);
      END;
    end;
 FINALLY
   FreeAndNil(JPG);
 end;
end;

TWICImage使用的来源(296 : ms)

Vcl.Graphics?调用中还有另一个类TWICImage处理 Microsoft Imaging 组件支持的图像

包括 BMP、GIF、ICO、JPEG、PNG、TIF 和 Windows Media 照片


在此处输入图像描述

procedure LoadImageFromStream(Stream: TStream; Image: TImage);
var
  wic: TWICImage;
  Bitmap: TBitmap;
begin
  Stream.Position := 0;
  wic := TWICImage.Create;
  try
    wic.LoadFromStream(Stream);
    Image.Picture.Assign(wic);
    Bitmap := TBitmap.Create;
    try
      Bitmap.PixelFormat := pf24bit;
      Bitmap.Width  := Image.Picture.Width;
      Bitmap.Height := Image.Picture.Height;
      Bitmap.Canvas.Draw(0, 0, Image.Picture.Graphic);
      Bitmap.SaveToFile('F:\ProgramFiles\Embarcadero\dtx\Projects\Bmp-DIB\TWICImage.bmp');
    finally
      Bitmap.Free;
    end;
  finally
    wic.Free;
  end;
end;

procedure RenderImage(const Filename: string);
var
  fs: TFileStream;
begin
  fs := TFileStream.Create(Filename, fmOpenRead);
  try
    LoadImageFromStream(fs, Form1.Image1);
  finally
    fs.Free;
  end;
end;

GetTickCount 用于所有测试例程。

procedure TForm1.Button1Click(Sender: TObject);
var
MyDIB   : TBitmap;
loadStr : string;
XStart,Xend   : LongWord;
begin
loadStr := 'F:\ProgramFiles\Embarcadero\dtx\Projects\Bmp-DIB\2018-10-17 14.04.23.jpg';
XStart := GetTickCount;

if RadioGroup1.ItemIndex = 0 then MyDIB := ConvertJPG2BMP(loadStr);// ConvertJPG2BMP()
if RadioGroup1.ItemIndex = 1 then TestBmp(loadStr);
if RadioGroup1.ItemIndex = 2 then RenderImage(loadStr);// TWICImage
if RadioGroup1.ItemIndex = 3 then GetOleGraphic(loadStr);

Xend := GetTickCount;
Label1.Caption := IntToStr(xEnd-XStart) + ' : MS' ;

end;

生成的图像与文件大小相同,仅来自函数GetOleGraphic()是生成的文件更小,分辨率更差?

这里是用于GetOleGraphic()的源

在此处输入图像描述


推荐阅读