将jpeg文件渲染到QWidget的最快方法是什么?

时间:2014-02-12 11:13:41

标签: qt jpeg qimage

我目前的代码如下:磁盘> bytearray> QImage(或QPixmap)>画家

// 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数据的bytearray转换为ppm的bytearray,可以更快地加载到QImage?

顺便说一句,使用QPixmap的时间与QImage相同。

3 个答案:

答案 0 :(得分:2)

我能够使用libjpeg-turbo显着减少QImage加载时间。以下是步骤

  • 第1步:在内存filebuffer
  • 中加载.jpeg
  • 步骤2a:使用tjDecompress2()filebuffer解压缩为uncompressedbuffer
  • 步骤2b:使用QImage(uncompressedbuffer, int width, int height, Format pixfmt)加载QImage
  • 第3步:渲染

QImage::loadFromData()

相比,步骤2a和2b组合提供了至少3倍的加速

注释

    libjpeg PixelFormat中使用的
  • tjDecompress2()应与步骤2b中指定的格式匹配
  • 您可以使用width
  • 派生步骤2b中使用的heighttjDecompressHeader2()

答案 1 :(得分:1)

我认为您的问题更多的是解决设计问题的最终结果,而不是设计问题本身。以下是我在GUI中与jpeg或图像的加载时间相关的想法。

从硬盘加载数据是软件设计的常见瓶颈。您必须让硬盘旋转到该位置并将其拉出并将其复制到ram。然后,当你准备好了,你有把它推到视频缓冲区或可能是显卡。

SSD速度会快得多,但在大多数情况下要求最终用户这一点并不实用。在启动时加载图像一次并且从不关闭程序是一种避免多次出现此延迟的方法。

这是为什么许多程序在启动时都有加载栏或启动画面的一个重要原因,因此在提取数据时它没有慢的用户体验。

程序处理更长过程的其他一些方法是使用经典沙漏,或旋转沙滩球,或者“稍等一下”GIF是常见的。

处理大量jpeg的最好例子可能是谷歌地图或一些高质量的照片管理程序,如Picasa。

谷歌地图存储了同一区域的许多不同分辨率,然后加载瓦片然后加载特定于可以查看的分辨率。 Picasa“处理”它找到的所有图像,并为每个图像存储一些不同的缩略图,这些缩略图的加载速度比全分辨率图像快得多(在大多数情况下)。

我的建议是以低分辨率存储jpeg的副本,加载一个,然后加载后,在加载时用高分辨率替换它,或者查看破坏图像进入瓷砖并根据需要加载它们。

在另一个相关的说明中,如果您的UI因jpeg加载而变慢,请将加载部分移动到一个线程中并保持您的UI响应!

希望有所帮助。

答案 2 :(得分:-2)

您询问了第三方软件 -

ImageMagick可以快速完成此任务(即使文件较大):

convert 1.jpg 2.jpg 3.jpg outputfilenamehere.ppm

当你打开文件流时,你可以做很多操作...... 希望有所帮助,              Gette