Jpeg到Bmp转换花费的时间不合理 [英] Jpeg to Bmp conversion takes unreasonable amount of time

查看:190
本文介绍了Jpeg到Bmp转换花费的时间不合理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有此功能需要4.2秒才能将jpg转换为bmp。
为什么要花这么长时间?我可以提高速度吗?

IrfanView可以在那一小段时间内加载并转换文件。



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

 功能ConvertJPG2BMP(CONST FileName:string):TBitmap; 
VAR JPG:TJpegImage;
开始
结果:= NIL;
JPG:= TJpegImage.Create;
尝试
JPG.LoadFromFile(FileName);
如果(JPG.Width> 0)AND(JPG.Width< 32768)
AND(JPG.Height> 0)AND(JPG.Height< 32768)然后
开始
结果:= TBitmap.Create;
TRY
Result.HandleType:= bmDIB;

// Fuji_FinePix_F550.JPG [3200x1800] [1.44MB]
Result.Assign(JPG); <-4秒!

FreeAndNil(Result);
END;
结尾;
最终
FreeAndNil(JPG);
结尾;
结尾;


解决方案

由于我只想测试稍旧一些的功能,这是一个很好的机会。



  function ConvertJPG2BMP(CONST FileName :string):TBitmap; 
VAR
JPG:TJpegImage;
开始
结果:= NIL;
JPG:= TJpegImage.Create;
尝试
JPG.LoadFromFile(FileName);
如果(JPG.Width> 0)AND(JPG.Width< 32768)
AND(JPG.Height> 0)AND(JPG.Height< 32768)AND
开始
结果:= TBitmap.Create;
尝试
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');

FreeAndNil(Result);
END;
结尾;
最终
FreeAndNil(JPG);
结尾;
结尾;






  procedure LoadImageFromStream(Stream:TStream; Image:TImage); 
var
wic:TWICImage;
位图:TBitmap;
开始
Stream.Position:= 0;
wic:= TWICImage.Create;
试试
wic.LoadFromStream(Stream);
Image.Picture.Assign(wic);
位图:= TBitmap.Create;
试试
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');
最后
位图。
结尾;
最终
wic。免费;
结尾;
结尾;

过程RenderImage(const Filename:string);
var
fs:TFileStream;
开始
fs:= TFileStream.Create(Filename,fmOpenRead);
试试
LoadImageFromStream(fs,Form1.Image1);
最终
fs。免费;
结尾;
结尾;

GetTickCount,用于所有经过测试的例程。

 程序TForm1.Button1Click(Sender:TObject); 
var
MyDIB:TBitmap;
loadStr:字符串;
XStart,Xend:LongWord;
begin
loadStr:=‘F:\ProgramFiles\Embarcadero\dtx\Projects\Bmp-DIB\2018-10-17 14.04.23.jpg’;
XStart:= GetTickCount;

如果RadioGroup1.ItemIndex = 0则MyDIB:= ConvertJPG2BMP(loadStr); // ConvertJPG2BMP()
如果RadioGroup1.ItemIndex = 1则TestBmp(loadStr);
如果RadioGroup1.ItemIndex = 2,则RenderImage(loadStr); // TWICImage
如果RadioGroup1.ItemIndex = 3,则GetOleGraphic(loadStr);

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

结尾;

生成的图像仅与函数 GetOleGraphic()是一个较小的文件,却产生了较差的分辨率?




I have this function that takes 4.2 seconds to convert a jpg to bmp. Why it takes so long? Can I make if faster?
IrfanView loads and converts the file in only a fraction of that time.

I thought that is spends most of the time in JPG.LoadFromFile. But when I measured the time I was surprised to see it spends most of the time in 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;

解决方案

Since I wanted to test the slightly older functions once, it is a good opportunity to do this now.

The sources used are here

These have been changed a bit in the code below.

Somewhat adapted source code of OP's 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;


The source for the TWICImage usage (296 : ms)

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


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 for all tested routines.

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;

The generated images are identical to the file size only from the function GetOleGraphic() is a smaller file produced with a worse resolution?

here the source used for the GetOleGraphic()

这篇关于Jpeg到Bmp转换花费的时间不合理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆