mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
A nice class for easily creating collages
This commit is contained in:
parent
929e50404e
commit
768b8ba990
@ -17,7 +17,7 @@ from PyQt5.Qt import (
|
|||||||
QLineEdit, QSpinBox, QTextEdit, QSize, QListWidgetItem, QIcon, QImage,
|
QLineEdit, QSpinBox, QTextEdit, QSize, QListWidgetItem, QIcon, QImage,
|
||||||
pyqtSignal, QStackedLayout, QWidget, QLabel, Qt, QComboBox, QPixmap,
|
pyqtSignal, QStackedLayout, QWidget, QLabel, Qt, QComboBox, QPixmap,
|
||||||
QGridLayout, QStyledItemDelegate, QModelIndex, QApplication, QStaticText,
|
QGridLayout, QStyledItemDelegate, QModelIndex, QApplication, QStaticText,
|
||||||
QStyle, QPen, QColor, QPainter
|
QStyle, QPen
|
||||||
)
|
)
|
||||||
|
|
||||||
from calibre import walk, fit_image, human_readable
|
from calibre import walk, fit_image, human_readable
|
||||||
@ -31,7 +31,7 @@ from calibre.utils.date import utcnow
|
|||||||
from calibre.utils.filenames import ascii_filename
|
from calibre.utils.filenames import ascii_filename
|
||||||
from calibre.utils.https import get_https_resource_securely, HTTPError
|
from calibre.utils.https import get_https_resource_securely, HTTPError
|
||||||
from calibre.utils.icu import numeric_sort_key as sort_key
|
from calibre.utils.icu import numeric_sort_key as sort_key
|
||||||
from calibre.utils.img import image_from_data, image_to_data
|
from calibre.utils.img import image_from_data, Canvas
|
||||||
from calibre.utils.zipfile import ZipFile, ZIP_STORED
|
from calibre.utils.zipfile import ZipFile, ZIP_STORED
|
||||||
from calibre.utils.filenames import atomic_rename
|
from calibre.utils.filenames import atomic_rename
|
||||||
from lzma.xz import compress, decompress
|
from lzma.xz import compress, decompress
|
||||||
@ -153,29 +153,26 @@ def default_cover_icons(cols=5):
|
|||||||
def create_cover(report, icons=(), cols=5, size=60, padding=8):
|
def create_cover(report, icons=(), cols=5, size=60, padding=8):
|
||||||
icons = icons or tuple(default_cover_icons(cols))
|
icons = icons or tuple(default_cover_icons(cols))
|
||||||
rows = int(math.ceil(len(icons) / cols))
|
rows = int(math.ceil(len(icons) / cols))
|
||||||
canvas = QImage(cols * (size + padding), rows * (size + padding), QImage.Format_RGB32)
|
with Canvas(cols * (size + padding), rows * (size + padding), bgcolor='#eee') as canvas:
|
||||||
canvas.fill(QColor('#eeeeee'))
|
y = -size - padding // 2
|
||||||
p = QPainter(canvas)
|
x = 0
|
||||||
y = -size - padding // 2
|
for i, icon in enumerate(icons):
|
||||||
x = 0
|
if i % cols == 0:
|
||||||
for i, icon in enumerate(icons):
|
y += padding + size
|
||||||
if i % cols == 0:
|
x = padding // 2
|
||||||
y += padding + size
|
else:
|
||||||
x = padding // 2
|
x += size + padding
|
||||||
else:
|
if report and icon in report.name_map:
|
||||||
x += size + padding
|
ipath = os.path.join(report.path, report.name_map[icon])
|
||||||
if report and icon in report.name_map:
|
else:
|
||||||
ipath = os.path.join(report.path, report.name_map[icon])
|
ipath = I(icon, allow_user_override=False)
|
||||||
else:
|
with lopen(ipath, 'rb') as f:
|
||||||
ipath = I(icon, allow_user_override=False)
|
img = image_from_data(f.read())
|
||||||
with lopen(ipath, 'rb') as f:
|
scaled, nwidth, nheight = fit_image(img.width(), img.height(), size, size)
|
||||||
img = image_from_data(f.read())
|
img = img.scaled(nwidth, nheight, Qt.IgnoreAspectRatio, Qt.SmoothTransformation)
|
||||||
scaled, nwidth, nheight = fit_image(img.width(), img.height(), size, size)
|
dx = (size - nwidth) // 2
|
||||||
img = img.scaled(nwidth, nheight, Qt.IgnoreAspectRatio, Qt.SmoothTransformation)
|
canvas.compose(img, x + dx, y)
|
||||||
dx = (size - nwidth) // 2
|
return canvas.export()
|
||||||
p.drawImage(x + dx, y, img)
|
|
||||||
p.end()
|
|
||||||
return image_to_data(canvas)
|
|
||||||
|
|
||||||
def verify_theme(report):
|
def verify_theme(report):
|
||||||
must_use_qt()
|
must_use_qt()
|
||||||
|
@ -168,6 +168,26 @@ def blend_on_canvas(img, width, height, bgcolor='#ffffff'):
|
|||||||
p.end()
|
p.end()
|
||||||
return nimg
|
return nimg
|
||||||
|
|
||||||
|
class Canvas(object):
|
||||||
|
|
||||||
|
def __init__(self, width, height, bgcolor='#ffffff'):
|
||||||
|
self.img = QImage(width, height, QImage.Format_RGB32)
|
||||||
|
self.img.fill(QColor(bgcolor))
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
self.painter = QPainter(self.img)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, *args):
|
||||||
|
self.painter.end()
|
||||||
|
|
||||||
|
def compose(self, img, x=0, y=0):
|
||||||
|
img = image_from_data(img)
|
||||||
|
self.painter.drawImage(x, y, img)
|
||||||
|
|
||||||
|
def export(self, fmt='JPEG', compression_quality=95):
|
||||||
|
return image_to_data(self.img, compression_quality=compression_quality, fmt=fmt)
|
||||||
|
|
||||||
def run_optimizer(file_path, cmd, as_filter=False, input_data=None):
|
def run_optimizer(file_path, cmd, as_filter=False, input_data=None):
|
||||||
file_path = os.path.abspath(file_path)
|
file_path = os.path.abspath(file_path)
|
||||||
cwd = os.path.dirname(file_path)
|
cwd = os.path.dirname(file_path)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user