Use the calibre PDF engine for image to PDF conversion

Will allow us to pass through JPG images unmodified
This commit is contained in:
Kovid Goyal 2019-07-09 15:27:10 +05:30
parent 8029b3cc83
commit 4815c6167e
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -4,11 +4,13 @@
from __future__ import absolute_import, division, print_function, unicode_literals from __future__ import absolute_import, division, print_function, unicode_literals
from PyQt5.Qt import QMarginsF, QPageLayout, QPageSize, QPainter, QPdfWriter, QSize from io import BytesIO
from calibre import fit_image from PyQt5.Qt import QMarginsF, QPageLayout, QPageSize, QSize
from calibre.ebooks.docx.writer.container import cicero, cm, didot, inch, mm, pica
from calibre.ebooks.pdf.render.common import cicero, cm, didot, inch, mm, pica
from calibre.ebooks.metadata.xmp import metadata_to_xmp_packet from calibre.ebooks.metadata.xmp import metadata_to_xmp_packet
from calibre.ebooks.pdf.render.serialize import PDFStream
from calibre.utils.img import image_from_path from calibre.utils.img import image_from_path
from calibre.utils.podofo import get_podofo, set_metadata_implementation from calibre.utils.podofo import get_podofo, set_metadata_implementation
@ -87,23 +89,21 @@ def get_page_layout(opts, for_comic=False):
# }}} # }}}
def draw_image_page(painter, img, preserve_aspect_ratio=True): def draw_image_page(writer, img, preserve_aspect_ratio=True):
page_rect = painter.viewport() ref = writer.add_image(img, img.cacheKey())
if preserve_aspect_ratio: page_size = tuple(writer.page_size)
aspect_ratio = float(img.width())/img.height() scaling = list(writer.page_size)
nw, nh = page_rect.width(), page_rect.height() translation = [0, 0]
if aspect_ratio > 1: img_ar = img.width() / img.height()
nh = int(page_rect.width()/aspect_ratio) page_ar = page_size[0]/page_size[1]
else: # Width is smaller than height if preserve_aspect_ratio and page_ar != img_ar:
nw = page_rect.height()*aspect_ratio if page_ar > img_ar:
__, nnw, nnh = fit_image(nw, nh, page_rect.width(), scaling[0] = img_ar * page_size[1]
page_rect.height()) translation[0] = (page_size[0] - scaling[0]) / 2
dx = int((page_rect.width() - nnw)/2.) else:
dy = int((page_rect.height() - nnh)/2.) scaling[1] = page_size[0] / img_ar
page_rect.translate(dx, dy) translation[1] = (page_size[1] - scaling[1]) / 2
page_rect.setHeight(nnh) writer.draw_image_with_transform(ref, translation=translation, scaling=scaling)
page_rect.setWidth(nnw)
painter.drawImage(page_rect, img)
def update_metadata(pdf_doc, pdf_metadata): def update_metadata(pdf_doc, pdf_metadata):
@ -115,28 +115,22 @@ def update_metadata(pdf_doc, pdf_metadata):
def convert(images, output_path, opts, metadata): def convert(images, output_path, opts, metadata):
writer = QPdfWriter(output_path) buf = BytesIO()
page_layout = get_page_layout(opts, for_comic=True)
page_size = page_layout.fullRectPoints().size()
writer = PDFStream(buf, (page_size.width(), page_size.height()), compress=True)
writer.apply_fill(color=(1, 1, 1))
pdf_metadata = PDFMetadata(metadata) pdf_metadata = PDFMetadata(metadata)
writer.setCreator(pdf_metadata.author) for i, path in enumerate(images):
writer.setTitle(pdf_metadata.title) img = image_from_path(path)
writer.setPageLayout(get_page_layout(opts, for_comic=True)) draw_image_page(writer, img)
painter = QPainter() writer.end_page()
painter.begin(writer) writer.end()
try:
for i, path in enumerate(images):
if i > 0:
writer.newPage()
img = image_from_path(path)
draw_image_page(painter, img)
finally:
painter.end()
podofo = get_podofo() podofo = get_podofo()
pdf_doc = podofo.PDFDoc() pdf_doc = podofo.PDFDoc()
with open(output_path, 'r+b') as f: pdf_doc.load(buf.getvalue())
raw = f.read() update_metadata(pdf_doc, pdf_metadata)
pdf_doc.load(raw) raw = pdf_doc.write()
update_metadata(pdf_doc, pdf_metadata) with open(output_path, 'wb') as f:
raw = pdf_doc.write()
f.seek(0), f.truncate()
f.write(raw) f.write(raw)