Add support for generating PDFs with losslessly encoded images
This patch adds the QPainter::LosslessImageRendering flag to QPainter::RenderHints and allows QPdfEngine to recognize it and encode images using a lossless data compression algorithm provided by zlib instead of using lossy JPEG compression, which can produce artifacts with some images. Task-number: QTBUG-54809 Change-Id: If9e2bc64da3bf3afcd5d6c74f0ee82336ef05a19 Reviewed-by: Lars Knoll <lars.knoll@qt.io>bb10
parent
5ea233ca67
commit
9cd527bc1f
|
|
@ -1437,6 +1437,13 @@ void QPainterPrivate::updateState(QPainterState *newState)
|
|||
by slightly less than half a pixel. Also will treat default constructed pens
|
||||
as cosmetic. Potentially useful when porting a Qt 4 application to Qt 5.
|
||||
|
||||
\value LosslessImageRendering Use a lossless image rendering, whenever possible.
|
||||
Currently, this hint is only used when QPainter is employed to output a PDF
|
||||
file through QPrinter or QPdfWriter, where drawImage()/drawPixmap() calls
|
||||
will encode images using a lossless compression algorithm instead of lossy
|
||||
JPEG compression.
|
||||
This value was added in Qt 5.13.
|
||||
|
||||
\sa renderHints(), setRenderHint(), {QPainter#Rendering
|
||||
Quality}{Rendering Quality}, {Concentric Circles Example}
|
||||
|
||||
|
|
|
|||
|
|
@ -91,7 +91,8 @@ public:
|
|||
SmoothPixmapTransform = 0x04,
|
||||
HighQualityAntialiasing = 0x08,
|
||||
NonCosmeticDefaultPen = 0x10,
|
||||
Qt4CompatiblePainting = 0x20
|
||||
Qt4CompatiblePainting = 0x20,
|
||||
LosslessImageRendering = 0x40,
|
||||
};
|
||||
Q_FLAG(RenderHint)
|
||||
|
||||
|
|
|
|||
|
|
@ -944,7 +944,8 @@ void QPdfEngine::drawPixmap (const QRectF &rectangle, const QPixmap &pixmap, con
|
|||
QPixmap pm = sourceRect != pixmap.rect() ? pixmap.copy(sourceRect) : pixmap;
|
||||
QImage image = pm.toImage();
|
||||
bool bitmap = true;
|
||||
const int object = d->addImage(image, &bitmap, pm.cacheKey());
|
||||
const bool lossless = painter()->testRenderHint(QPainter::LosslessImageRendering);
|
||||
const int object = d->addImage(image, &bitmap, lossless, pm.cacheKey());
|
||||
if (object < 0)
|
||||
return;
|
||||
|
||||
|
|
@ -972,7 +973,8 @@ void QPdfEngine::drawImage(const QRectF &rectangle, const QImage &image, const Q
|
|||
QRect sourceRect = sr.toRect();
|
||||
QImage im = sourceRect != image.rect() ? image.copy(sourceRect) : image;
|
||||
bool bitmap = true;
|
||||
const int object = d->addImage(im, &bitmap, im.cacheKey());
|
||||
const bool lossless = painter()->testRenderHint(QPainter::LosslessImageRendering);
|
||||
const int object = d->addImage(im, &bitmap, lossless, im.cacheKey());
|
||||
if (object < 0)
|
||||
return;
|
||||
|
||||
|
|
@ -2578,6 +2580,8 @@ int QPdfEnginePrivate::addConstantAlphaObject(int brushAlpha, int penAlpha)
|
|||
|
||||
int QPdfEnginePrivate::addBrushPattern(const QTransform &m, bool *specifyColor, int *gStateObject)
|
||||
{
|
||||
Q_Q(QPdfEngine);
|
||||
|
||||
int paintType = 2; // Uncolored tiling
|
||||
int w = 8;
|
||||
int h = 8;
|
||||
|
|
@ -2607,7 +2611,8 @@ int QPdfEnginePrivate::addBrushPattern(const QTransform &m, bool *specifyColor,
|
|||
return 0;
|
||||
QImage image = brush.textureImage();
|
||||
bool bitmap = true;
|
||||
imageObject = addImage(image, &bitmap, image.cacheKey());
|
||||
const bool lossless = q->painter()->testRenderHint(QPainter::LosslessImageRendering);
|
||||
imageObject = addImage(image, &bitmap, lossless, image.cacheKey());
|
||||
if (imageObject != -1) {
|
||||
QImage::Format f = image.format();
|
||||
if (f != QImage::Format_MonoLSB && f != QImage::Format_Mono) {
|
||||
|
|
@ -2669,7 +2674,7 @@ static inline bool is_monochrome(const QVector<QRgb> &colorTable)
|
|||
/*!
|
||||
* Adds an image to the pdf and return the pdf-object id. Returns -1 if adding the image failed.
|
||||
*/
|
||||
int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_no)
|
||||
int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, bool lossless, qint64 serial_no)
|
||||
{
|
||||
if (img.isNull())
|
||||
return -1;
|
||||
|
|
@ -2730,7 +2735,7 @@ int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_n
|
|||
bool hasAlpha = false;
|
||||
bool hasMask = false;
|
||||
|
||||
if (QImageWriter::supportedImageFormats().contains("jpeg") && !grayscale) {
|
||||
if (QImageWriter::supportedImageFormats().contains("jpeg") && !grayscale && !lossless) {
|
||||
QBuffer buffer(&imageData);
|
||||
QImageWriter writer(&buffer, "jpeg");
|
||||
writer.setQuality(94);
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ public:
|
|||
void writeHeader();
|
||||
void writeTail();
|
||||
|
||||
int addImage(const QImage &image, bool *bitmap, qint64 serial_no);
|
||||
int addImage(const QImage &image, bool *bitmap, bool lossless, qint64 serial_no);
|
||||
int addConstantAlphaObject(int brushAlpha, int penAlpha = 255);
|
||||
int addBrushPattern(const QTransform &matrix, bool *specifyColor, int *gStateObject);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue