mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Pass JPEG images unmodified when creating PDF image pages
This commit is contained in:
parent
4815c6167e
commit
22ba6c3ab7
@ -178,7 +178,7 @@ class PDFOutput(OutputFormatPlugin):
|
||||
|
||||
def convert_images(self, images):
|
||||
from calibre.ebooks.pdf.image_writer import convert
|
||||
convert(images, self.output_path, self.opts, self.metadata)
|
||||
convert(images, self.output_path, self.opts, self.metadata, self.report_progress)
|
||||
|
||||
def get_cover_data(self):
|
||||
oeb = self.oeb
|
||||
|
@ -5,22 +5,20 @@
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
|
||||
import os
|
||||
from io import BytesIO
|
||||
|
||||
from PyQt5.Qt import (
|
||||
QApplication, QBuffer, QMarginsF, QPageLayout, QPainter, QPdfWriter, QTimer,
|
||||
QUrl
|
||||
)
|
||||
from PyQt5.Qt import QApplication, QTimer, QUrl
|
||||
from PyQt5.QtWebEngineWidgets import QWebEnginePage
|
||||
|
||||
from calibre.constants import iswindows
|
||||
from calibre.ebooks.oeb.polish.container import Container as ContainerBase
|
||||
from calibre.ebooks.oeb.polish.split import merge_html
|
||||
from calibre.ebooks.pdf.image_writer import (
|
||||
PDFMetadata, draw_image_page, get_page_layout, update_metadata
|
||||
Image, PDFMetadata, draw_image_page, get_page_layout, update_metadata
|
||||
)
|
||||
from calibre.ebooks.pdf.render.serialize import PDFStream
|
||||
from calibre.gui2 import setup_unix_signals
|
||||
from calibre.gui2.webengine import secure_webengine
|
||||
from calibre.utils.img import image_from_data
|
||||
from calibre.utils.logging import default_log
|
||||
from calibre.utils.podofo import get_podofo
|
||||
from polyglot.builtins import range
|
||||
@ -103,20 +101,14 @@ class Renderer(QWebEnginePage):
|
||||
|
||||
|
||||
def add_cover(pdf_doc, cover_data, page_layout, opts):
|
||||
buf = QBuffer()
|
||||
buf.open(QBuffer.ReadWrite)
|
||||
cover_layout = QPageLayout(page_layout)
|
||||
cover_layout.setMargins(QMarginsF(0, 0, 0, 0))
|
||||
img = image_from_data(cover_data)
|
||||
writer = QPdfWriter(buf)
|
||||
writer.setPageLayout(cover_layout)
|
||||
painter = QPainter()
|
||||
painter.begin(writer)
|
||||
try:
|
||||
draw_image_page(painter, img, preserve_aspect_ratio=opts.preserve_cover_aspect_ratio)
|
||||
finally:
|
||||
painter.end()
|
||||
cover_pdf = buf.data().data()
|
||||
buf = BytesIO()
|
||||
page_size = page_layout.fullRectPoints().size()
|
||||
img = Image(cover_data)
|
||||
writer = PDFStream(buf, (page_size.width(), page_size.height()), compress=True)
|
||||
writer.apply_fill(color=(1, 1, 1))
|
||||
draw_image_page(writer, img, preserve_aspect_ratio=opts.preserve_cover_aspect_ratio)
|
||||
writer.end()
|
||||
cover_pdf = buf.getvalue()
|
||||
podofo = get_podofo()
|
||||
cover_pdf_doc = podofo.PDFDoc()
|
||||
cover_pdf_doc.load(cover_pdf)
|
||||
|
@ -8,11 +8,14 @@ from io import BytesIO
|
||||
|
||||
from PyQt5.Qt import QMarginsF, QPageLayout, QPageSize, QSize
|
||||
|
||||
from calibre.ebooks.pdf.render.common import cicero, cm, didot, inch, mm, pica
|
||||
from calibre.constants import filesystem_encoding
|
||||
from calibre.ebooks.metadata.xmp import metadata_to_xmp_packet
|
||||
from calibre.ebooks.pdf.render.common import cicero, cm, didot, inch, mm, pica
|
||||
from calibre.ebooks.pdf.render.serialize import PDFStream
|
||||
from calibre.utils.img import image_from_path
|
||||
from calibre.utils.img import image_and_format_from_data
|
||||
from calibre.utils.imghdr import identify
|
||||
from calibre.utils.podofo import get_podofo, set_metadata_implementation
|
||||
from polyglot.builtins import as_unicode
|
||||
|
||||
|
||||
class PDFMetadata(object): # {{{
|
||||
@ -89,12 +92,34 @@ def get_page_layout(opts, for_comic=False):
|
||||
# }}}
|
||||
|
||||
|
||||
class Image(object): # {{{
|
||||
|
||||
def __init__(self, path_or_bytes):
|
||||
if not isinstance(path_or_bytes, bytes):
|
||||
with open(path_or_bytes, 'rb') as f:
|
||||
path_or_bytes = f.read()
|
||||
self.img_data = path_or_bytes
|
||||
fmt, width, height = identify(path_or_bytes)
|
||||
if width > 0 and height > 0 and fmt == 'jpeg':
|
||||
self.fmt = fmt
|
||||
self.width, self.height = width, height
|
||||
self.cache_key = None
|
||||
else:
|
||||
self.img, self.fmt = image_and_format_from_data(path_or_bytes)
|
||||
self.width, self.height = self.img.width(), self.img.height()
|
||||
self.cache_key = self.img.cacheKey()
|
||||
# }}}
|
||||
|
||||
|
||||
def draw_image_page(writer, img, preserve_aspect_ratio=True):
|
||||
ref = writer.add_image(img, img.cacheKey())
|
||||
if img.fmt == 'jpeg':
|
||||
ref = writer.add_jpeg_image(img.img_data, img.width, img.height, img.cache_key)
|
||||
else:
|
||||
ref = writer.add_image(img.img, img.cache_key)
|
||||
page_size = tuple(writer.page_size)
|
||||
scaling = list(writer.page_size)
|
||||
translation = [0, 0]
|
||||
img_ar = img.width() / img.height()
|
||||
img_ar = img.width / img.height
|
||||
page_ar = page_size[0]/page_size[1]
|
||||
if preserve_aspect_ratio and page_ar != img_ar:
|
||||
if page_ar > img_ar:
|
||||
@ -114,7 +139,7 @@ def update_metadata(pdf_doc, pdf_metadata):
|
||||
pdf_metadata.mi.book_producer, pdf_metadata.mi.tags, xmp_packet)
|
||||
|
||||
|
||||
def convert(images, output_path, opts, metadata):
|
||||
def convert(images, output_path, opts, metadata, report_progress):
|
||||
buf = BytesIO()
|
||||
page_layout = get_page_layout(opts, for_comic=True)
|
||||
page_size = page_layout.fullRectPoints().size()
|
||||
@ -122,7 +147,7 @@ def convert(images, output_path, opts, metadata):
|
||||
writer.apply_fill(color=(1, 1, 1))
|
||||
pdf_metadata = PDFMetadata(metadata)
|
||||
for i, path in enumerate(images):
|
||||
img = image_from_path(path)
|
||||
img = Image(as_unicode(path, filesystem_encoding))
|
||||
draw_image_page(writer, img)
|
||||
writer.end_page()
|
||||
writer.end()
|
||||
|
@ -416,6 +416,9 @@ class PDFStream(object):
|
||||
self.objects.commit(r, self.stream)
|
||||
return r
|
||||
|
||||
def add_jpeg_image(self, img_data, w, h, cache_key=None):
|
||||
return self.write_image(img_data, w, h, 32, dct=True)
|
||||
|
||||
def add_image(self, img, cache_key):
|
||||
ref = self.get_image(cache_key)
|
||||
if ref is not None:
|
||||
|
Loading…
x
Reference in New Issue
Block a user