From 56f7d7cad4f2203b37bfb4307a7ab71a2f82f192 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 6 May 2016 21:16:20 +0530 Subject: [PATCH] A more sensible API to set PNG compression levels --- src/calibre/utils/img.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/calibre/utils/img.py b/src/calibre/utils/img.py index 38fa2cc8f7..09f8dbacb5 100644 --- a/src/calibre/utils/img.py +++ b/src/calibre/utils/img.py @@ -7,7 +7,7 @@ from __future__ import (unicode_literals, division, absolute_import, import os, subprocess, errno, shutil, tempfile from threading import Thread -from PyQt5.Qt import QImage, QByteArray, QBuffer, Qt, QImageReader, QColor +from PyQt5.Qt import QImage, QByteArray, QBuffer, Qt, QImageReader, QColor, QImageWriter from calibre import fit_image, force_unicode from calibre.constants import iswindows, plugins @@ -84,15 +84,24 @@ def blend_image(img, bgcolor='#ffffff'): overlay(img, nimg) return nimg -def image_to_data(img, compression_quality=95, fmt='JPEG'): +def image_to_data(img, compression_quality=95, fmt='JPEG', png_compression_level=9): + ''' Serialize image to bytestring in the specified format. + compression_quality is for JPEG and goes from 0 to 100. + png_compression_level is for PNG and goes from 0-9 ''' ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) fmt = fmt.upper() + w = QImageWriter(buf, fmt.encode('ascii')) if img.hasAlphaChannel() and fmt in 'JPEG JPG'.split(): img = blend_image(img) - if not img.save(buf, fmt, quality=compression_quality): - raise ValueError('Failed to export image as ' + fmt) + if fmt == 'PNG': + cl = min(9, max(0, png_compression_level)) + w.setQuality(10 * (9-cl)) + else: + w.setQuality(compression_quality) + if not w.write(img): + raise ValueError('Failed to export image as ' + fmt + ' with error: ' + w.errorString()) return ba.data() def resize_image(img, width, height):