Search code examples
qtjpegqimage

What is the fastest way to render a jpeg file on to a QWidget?


My current code follows this: Disk > bytearray > QImage (or 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 QImage();
this->mRenderImg->loadFromData(blob, "JPG");

// Step 3: render
QPainter p(this);
QRect target; // draw rectangle
p.drawImage(target, *(this->mRenderImg));

Step 1 takes 0.5s
Step 2 takes 3.0s - decoding jpeg is the slowest step
Step 3 takes 0.1s

Apparently, decoding jpeg data is the slowest step. How do I make it faster?

Is there a third party library that can transform bytearray of jpeg data to bytearray of ppm that can be loaded to QImage faster?

Btw, Using QPixmap takes the same time as QImage.


Solution

  • I was able to reduce QImage load time significantly using libjpeg-turbo. Here are the steps

    • Step 1: Load .jpeg in memory filebuffer
    • Step 2a: Use tjDecompress2() to decompress filebuffer to uncompressedbuffer
    • Step 2b: Use QImage(uncompressedbuffer, int width, int height, Format pixfmt) to load the QImage
    • Step 3: Render

    Step 2a and 2b combined offers atleast 3x speedup compared to QImage::loadFromData()

    Notes

    • PixelFormat used in libjpeg's tjDecompress2() should match with format specified in step 2b
    • You can derive the width and height used in step 2b using tjDecompressHeader2()