EPUB Output: Do not shrink images to fit the screen size by default.

This matches behavior of converting to other formats. A new option has
been added to the EPUB Output section to control the maximum size of
images.
This commit is contained in:
Kovid Goyal 2023-04-04 17:38:25 +05:30
parent c7636ad90d
commit c33df89ce2
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
6 changed files with 106 additions and 64 deletions

View File

@ -278,7 +278,7 @@ OPTIONS = {
'epub': (
'dont_split_on_page_breaks', 'flow_size', 'no_default_epub_cover',
'no_svg_cover', 'epub_inline_toc', 'epub_toc_at_end', 'toc_title',
'preserve_cover_aspect_ratio', 'epub_flatten', 'epub_version'),
'preserve_cover_aspect_ratio', 'epub_flatten', 'epub_version', 'epub_max_image_size',),
'fb2': ('sectionize', 'fb2_genre'),

View File

@ -124,6 +124,17 @@ class EPUBOutput(OutputFormatPlugin):
' actually need it.')
),
OptionRecommendation(name='epub_max_image_size', recommended_value='none',
help=_('The maximum image size (width x height). A value of {0} means use the screen size from the output'
' profile. A value of {1} means no maximum size is specified. For example, a value of {2}'
' will cause all images to be resized so that their width is no more than {3} pixels and'
' their height is no more than {4} pixels. Note that this only affects the size of the actual'
' image files themselves. Any given image may be rendered at a different size depending on the styling'
' applied to it in the document.'
).format('none', 'profile', '100x200', 100, 200)
),
}
recommendations = {('pretty_print', True, OptionRecommendation.HIGH)}
@ -196,8 +207,9 @@ class EPUBOutput(OutputFormatPlugin):
self.workaround_ade_quirks()
self.workaround_webkit_quirks()
self.upshift_markup()
from calibre.ebooks.oeb.transforms.rescale import RescaleImages
RescaleImages(check_colorspaces=True)(oeb, opts)
RescaleImages(check_colorspaces=True)(oeb, opts, max_size=self.opts.epub_max_image_size)
from calibre.ebooks.oeb.transforms.split import Split
split = Split(not self.opts.dont_split_on_page_breaks,
@ -385,7 +397,6 @@ class EPUBOutput(OutputFormatPlugin):
from calibre.ebooks.oeb.base import XPath, XHTML, barename, urlunquote
stylesheet = self.oeb.manifest.main_stylesheet
# ADE cries big wet tears when it encounters an invalid fragment
# identifier in the NCX toc.
frag_pat = re.compile(r'[-A-Za-z0-9_:.]+$')

View File

@ -140,7 +140,7 @@ OptionRecommendation(name='output_profile',
choices=[x.short_name for x in output_profiles()],
help=_('Specify the output profile. The output profile '
'tells the conversion system how to optimize the '
'created document for the specified device (such as by resizing images for the device screen size). In some cases, '
'created document for the specified device. In some cases, '
'an output profile can be used to optimize the output for a particular device, but this is rarely necessary. '
'Choices are:') + ', '.join([
x.short_name for x in output_profiles()])

View File

@ -15,11 +15,11 @@ class RescaleImages:
def __init__(self, check_colorspaces=False):
self.check_colorspaces = check_colorspaces
def __call__(self, oeb, opts):
def __call__(self, oeb, opts, max_size: str = 'profile'):
self.oeb, self.opts, self.log = oeb, opts, oeb.log
self.rescale()
self.rescale(max_size)
def rescale(self):
def rescale(self, max_size: str = 'profile'):
from PIL import Image
from io import BytesIO
@ -32,6 +32,23 @@ class RescaleImages:
page_width -= (self.opts.margin_left + self.opts.margin_right) * self.opts.dest.dpi/72
page_height -= (self.opts.margin_top + self.opts.margin_bottom) * self.opts.dest.dpi/72
no_scale_size = 99999999999
if max_size == 'none':
page_width = page_height = no_scale_size
elif max_size != 'profile':
w, __, h = max_size.strip().lower().partition('x')
try:
page_width = int(w.strip())
except Exception:
page_width = no_scale_size
if page_width <= 0:
page_width = no_scale_size
try:
page_height = int(h.strip())
except Exception:
page_height = no_scale_size
if page_height <= 0:
page_height = no_scale_size
for item in self.oeb.manifest:
if item.media_type.startswith('image'):
ext = item.media_type.split('/')[-1].upper()

View File

@ -14,10 +14,27 @@
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="1">
<widget class="QCheckBox" name="opt_preserve_cover_aspect_ratio">
<item row="7" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Preserve cover &amp;aspect ratio</string>
<string>EP&amp;UB version:</string>
</property>
<property name="buddy">
<cstring>opt_epub_version</cstring>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="opt_no_default_epub_cover">
<property name="text">
<string>No default &amp;cover</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="opt_epub_inline_toc">
<property name="text">
<string>Insert inline &amp;Table of Contents</string>
</property>
</widget>
</item>
@ -31,6 +48,46 @@
</property>
</widget>
</item>
<item row="8" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>262</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="opt_no_svg_cover">
<property name="text">
<string>No &amp;SVG cover</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QComboBox" name="opt_epub_version"/>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="opt_epub_flatten">
<property name="text">
<string>&amp;Flatten EPUB file structure</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>&amp;Title for inserted ToC:</string>
</property>
<property name="buddy">
<cstring>opt_toc_title</cstring>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="opt_flow_size">
<property name="specialValueText">
@ -50,47 +107,6 @@
</property>
</widget>
</item>
<item row="7" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>262</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="opt_no_default_epub_cover">
<property name="text">
<string>No default &amp;cover</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="opt_no_svg_cover">
<property name="text">
<string>No &amp;SVG cover</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="opt_epub_inline_toc">
<property name="text">
<string>Insert inline &amp;Table of Contents</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="opt_dont_split_on_page_breaks">
<property name="text">
<string>Do not &amp;split on page breaks</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="opt_epub_toc_at_end">
<property name="text">
@ -98,20 +114,17 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="opt_epub_flatten">
<item row="2" column="1">
<widget class="QCheckBox" name="opt_preserve_cover_aspect_ratio">
<property name="text">
<string>&amp;Flatten EPUB file structure</string>
<string>Preserve cover &amp;aspect ratio</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_2">
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="opt_dont_split_on_page_breaks">
<property name="text">
<string>&amp;Title for inserted ToC:</string>
</property>
<property name="buddy">
<cstring>opt_toc_title</cstring>
<string>Do not &amp;split on page breaks</string>
</property>
</widget>
</item>
@ -123,17 +136,17 @@
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_3">
<widget class="QLabel" name="label_4">
<property name="text">
<string>EP&amp;UB version:</string>
<string>Shrink &amp;images larger than:</string>
</property>
<property name="buddy">
<cstring>opt_epub_version</cstring>
<cstring>opt_epub_max_image_size</cstring>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QComboBox" name="opt_epub_version"/>
<widget class="QLineEdit" name="opt_epub_max_image_size"/>
</item>
</layout>
</widget>

View File

@ -540,6 +540,7 @@ def epub_output(container):
g.appendChild(checkbox('epub_toc_at_end', _('Put inserted Table of Contents at the &end of the book')))
g.appendChild(lineedit('toc_title', _('&Title for inserted ToC:')))
g.appendChild(int_spin('flow_size', _('Split files &larger than:'), unit='KB', max=1000000, step=20))
g.appendChild(lineedit('epub_max_image_size', _('Shrink &images larger than:')))
g.appendChild(choices('epub_version', _('EP&UB version:'), ui_data.versions))
# }}}