delphi - 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;
解决方案
由于我想测试一次稍微旧的功能,现在是一个很好的机会。
这些已经在下面的代码中进行了一些更改。
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()
是生成的文件更小,分辨率更差?
推荐阅读
- html - 将表格单元内的按钮移动到中心
- java - RXTX 串口读取字节数
- php - 如果 json 中的相同 id 通过 php 替换值
- c - 从读取文件c语言中修改第一个数字
- django - * 之后的 schedule_task() 参数必须是可迭代的,而不是 int
- javascript - ldapjs 无法连接服务器
- reactjs - 基于其他属性值的条件类型
- android - 无法构建 React Native 签名版本
- reactjs - 在 Redux 中添加到具有可变键的对象列表
- kubernetes - Kubernetes 的多个 hostPath volumeMounts:只有一个有效