diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 768f3b713..149f0fc95 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -314,6 +314,11 @@ bool QImageData::checkForAlphaPixels() const in caching and short-lived transfers such as sending QImage trough socket. + The image format is lossy for fully opaque and lossless for + images with alpha pixels by default. If guaranteed lossless + quality is required use QImageWriter::setQuality() to set the + quality to best (100). + Your code should be prepared to discard any image in that format and generate a new image in case loading fails as the format (its header and the way image data is stored) may change diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp index 5215101ad..a4d1dced1 100644 --- a/src/gui/image/qimagewriter.cpp +++ b/src/gui/image/qimagewriter.cpp @@ -166,7 +166,7 @@ QImageWriterPrivate::QImageWriterPrivate() : device(nullptr), deleteDevice(false), handler(nullptr), - quality(100), + quality(-1), compression(1), gamma(0.0), imageWriterError(QImageWriter::UnknownError) @@ -336,7 +336,7 @@ void QImageWriter::setQuality(int quality) } /*! - Returns the quality level of the image. Default value is 100. + Returns the quality level of the image. Default value is -1. \sa setQuality() */ diff --git a/src/gui/image/qkathandler.cpp b/src/gui/image/qkathandler.cpp index 915ca88fa..abb259f86 100644 --- a/src/gui/image/qkathandler.cpp +++ b/src/gui/image/qkathandler.cpp @@ -34,7 +34,8 @@ QT_BEGIN_NAMESPACE QKatHandler::QKatHandler() - : m_complevel(1) + : m_complevel(1), + m_quality(75) { } @@ -134,7 +135,11 @@ bool QKatHandler::write(const QImage &image) return false; } - const QImage image32 = image.convertToFormat(image.d->checkForAlphaPixels() ? QImage::Format_ARGB32 : QImage::Format_RGB16); + QImage::Format imageformat = QImage::Format_ARGB32; + if (Q_LIKELY(m_quality <= 75)) { + imageformat = (image.d->checkForAlphaPixels() ? QImage::Format_ARGB32 : QImage::Format_RGB16); + } + const QImage image32 = image.convertToFormat(imageformat); struct libdeflate_compressor* comp = libdeflate_alloc_compressor(m_complevel); if (Q_UNLIKELY(!comp)) { @@ -179,9 +184,7 @@ bool QKatHandler::write(const QImage &image) QVariant QKatHandler::option(QImageIOHandler::ImageOption option) const { - if (option == QImageIOHandler::CompressionLevel) { - return QVariant(m_complevel); - } else if (option == QImageIOHandler::Size) { + if (option == QImageIOHandler::Size) { QDataStream imagestream(device()); QSTACKARRAY(char, header, 5); @@ -198,6 +201,10 @@ QVariant QKatHandler::option(QImageIOHandler::ImageOption option) const imagestream >> width; imagestream >> height; return QSize(width, height); + } else if (option == QImageIOHandler::CompressionLevel) { + return QVariant(m_complevel); + } else if (option == QImageIOHandler::Quality) { + return QVariant(m_quality); } return QVariant(); } @@ -212,12 +219,33 @@ void QKatHandler::setOption(QImageIOHandler::ImageOption option, const QVariant } else { m_complevel = newcomplevel; } + } else if (option == QImageIOHandler::Quality) { + const int newquality = value.toInt(); + if (newquality == -1) { + m_quality = 75; + } else if (Q_UNLIKELY(newquality < 0 || newquality > 100)) { + qWarning("QKatHandler::setOption() Invalid quality (%d)", newquality); + m_quality = 75; + } else { + m_quality = newquality; + } } } bool QKatHandler::supportsOption(QImageIOHandler::ImageOption option) const { - return (option == QImageIOHandler::CompressionLevel || option == QImageIOHandler::Size); + switch (option) { + case QImageIOHandler::Size: + case QImageIOHandler::CompressionLevel: + case QImageIOHandler::Quality: { + return true; + } + default: { + return false; + } + } + Q_UNREACHABLE(); + return false; } QByteArray QKatHandler::name() const diff --git a/src/gui/image/qkathandler_p.h b/src/gui/image/qkathandler_p.h index 8b48ff4b3..978ba3d65 100644 --- a/src/gui/image/qkathandler_p.h +++ b/src/gui/image/qkathandler_p.h @@ -57,6 +57,7 @@ public: private: int m_complevel; + int m_quality; }; QT_END_NAMESPACE