Qt 在QWidget上渲染jpeg文件的最快方法是什么?
我当前的代码如下:Disk>bytearray>QImage(或QPixmap)>PainterQt 在QWidget上渲染jpeg文件的最快方法是什么?,qt,jpeg,qimage,Qt,Jpeg,Qimage,我当前的代码如下:Disk>bytearray>QImage(或QPixmap)>Painter // Step 1: disk to qbytearray QFile file("/path/to/file"); file.open(QIODevice::ReadOnly); QByteArray blob = file.readAll(); file.close(); // Step 2: bytearray to QImage this->mRenderImg = new QIma
// Step 1: disk to qbytearray
QFile file("/path/to/file");
file.open(QIODevice::ReadOnly);
QByteArray blob = file.readAll();
file.close();
// Step 2: bytearray to QImage
this->mRenderImg = new QImage();
this->mRenderImg->loadFromData(blob, "JPG");
// Step 3: render
QPainter p(this);
QRect target; // draw rectangle
p.drawImage(target, *(this->mRenderImg));
步骤1需要0.5秒步骤2需要3.0秒-解码jpeg是最慢的步骤
步骤3需要0.1秒 显然,解码jpeg数据是最慢的一步。我如何使它更快 是否有第三方库可以将jpeg数据的字节数组转换为ppm的字节数组,从而更快地加载到QImage
顺便说一句,使用
QPixmap
与QImage
花费的时间相同,我认为您的问题更多的是解决设计问题的最终结果,而不是设计问题本身。以下是我对在GUI中加载JPEG或图像的时间的看法
从硬盘加载数据是软件设计的一个常见瓶颈。您必须让硬盘驱动器旋转到该位置,然后将其拉出并复制到ram中。然后,当你准备好了,你有ram推它到视频缓冲区或可能到图形卡
SSD会快得多,但在大多数情况下,要求最终用户这样做是不现实的。在启动时加载映像一次,并且永远不要关闭程序,这是避免多次出现此延迟的一种方法
这就是为什么很多程序在启动时都有一个加载条或启动屏幕的一个重要原因,这样在启动数据时就不会有缓慢的用户体验
程序处理较长进程的其他一些方法是使用经典的计时玻璃、旋转沙滩球或“稍等”GIF
处理大量大型JPEG的最好例子可能是谷歌地图或一些更高质量的照片管理程序,如Picasa
Google maps存储同一区域的许多不同分辨率,并平铺,然后加载特定于可查看分辨率的图像。Picasa“处理”它找到的所有图像,并为每个图像存储一些不同的缩略图,这些缩略图的加载速度比全分辨率图像快得多(在大多数情况下)
我的建议是,要么以较低的分辨率存储一份jpeg,加载一份,然后在加载后,在加载时将其替换为高分辨率的一份,要么考虑将图像分块并根据需要加载它们
另一个相关的注意事项是,如果您的UI由于jpeg加载而变慢,请将加载部分移动到线程中,并保持UI响应
希望这能有所帮助。我使用libjpeg-turbo可以显著缩短QImage的加载时间。以下是步骤
- 步骤1:在内存中加载.jpeg
filebuffer
- 步骤2a:使用
将tjDecompress2()
解压缩为filebuffer
uncompressedbuffer
- 步骤2b:使用
加载QImageQImage(uncompressedbuffer,int-width,int-height,Format-pixfmt)
- 步骤3:渲染
QImage::loadFromData()
注释
- libjpeg的
中使用的tjDecompress2()
应与步骤2b中指定的格式匹配PixelFormat
- 您可以使用
tjDecompressHeader2()
Gette您是否在
paintEvent
中解码jpeg?有必要吗?您是否尝试使用QLabel
和QLabel::setPixmap
?我的目标是尽可能减少从磁盘读取.jpg映像文件并将其加载到QImage
(或QPixmap
)所需的时间。加载QImage
后,渲染速度非常快-无论是在QLabel
还是任何其他小部件上。我提到渲染部分的原因是为了表明我对一个解决方案持开放态度,该解决方案不涉及使用Qt提供的类,如QImage
或QPixmap
QByteArray
和QImage
步骤是不必要的。您应该通过将文件名传递给其构造函数直接创建QPixmap
:QPixmap(“/path/to/file”)
@PavelStrakhovQPixmap px(“path/to/file”)
只是缩短了代码,但与步骤1和步骤2的组合时间相同。我已经测试过了。在我的问题中,我有意将这两个步骤分开,因为由于磁盘延迟,我在步骤1中看不到任何优化范围。但我在第2步中看到了一个优化范围。我已经准备好沙漏/旋转器和线程-所以UI冻结不是一个问题。话虽如此,在我们的例子中,更快地加载图像将有其他与性能相关的好处。现在,将文件加载到QImage
可以分为两个步骤-从磁盘读取(我问题中的步骤1)和从该数据初始化QImage对象(步骤2)。我知道步骤1无法优化,因为它涉及磁盘io延迟,但步骤2可能可以优化。因此,问题是我们无法控制用户的数据。因此,不幸的是,这些选项已经关闭