Search code examples
qtqmlpngjpegimage-compression

Qt: Saving an image in intended compression format


I am using Qt and saving a image file out of a QML UI item. Following is what I do

auto screenshot = quick_item->grabToImage();
screenshot->saveToFile("/somepath/filename.jpeg");
// OR sometimes use like png like
screenshot->saveToFile("/somepath/filename.png");

This is works fantastically well on all platforms. I open the file the image is saved as intended.

Now my question is:
I just mentioned .jpeg as file extension while providing the filename as param into saveToFile. This works but, should I need to use QImageWriter to ensure that the image is actually compressed in jpeg/png format ?

What happens when it is a lossy compression like jpeg?
How to control a lossy compression if I want to like in android I can do a image.compress(CompressFormat.JPEG, 80, stream) where 80 is the percentage of quality for Compress ?


Solution

  • You can't do that directly from QQuickItemGrabResult, you have to use QImage::save() for that :

    auto screenshot = quick_item->grabToImage();
    auto image = screenshot->image();
    image.save("/somepath/filename.jpeg", nullptr, 80);
    

    The second parameter of save is the format, but it can be left null and then be guessed based on the filename extension, the third one is the compression quality.

    The quality factor has no effect if you use a lossless format like png. You can set it at -1 (the default value), omit the parameter or use a factor that you would use for lossy format.

    EDIT: as pointed by @Arsenal, the quality factor maps to compression levels for lossless formats (those that support it). For example in PNG, quality 0 maps to PNG compression level 9 (smallest file size) and 100 to PNG compression level 0 (biggest file size). The default quality for PNG in Qt is 50, mapping to a PNG compression level of 4.