mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
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:
parent
c7636ad90d
commit
c33df89ce2
@ -278,7 +278,7 @@ OPTIONS = {
|
|||||||
'epub': (
|
'epub': (
|
||||||
'dont_split_on_page_breaks', 'flow_size', 'no_default_epub_cover',
|
'dont_split_on_page_breaks', 'flow_size', 'no_default_epub_cover',
|
||||||
'no_svg_cover', 'epub_inline_toc', 'epub_toc_at_end', 'toc_title',
|
'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'),
|
'fb2': ('sectionize', 'fb2_genre'),
|
||||||
|
|
||||||
|
@ -124,6 +124,17 @@ class EPUBOutput(OutputFormatPlugin):
|
|||||||
' actually need it.')
|
' 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)}
|
recommendations = {('pretty_print', True, OptionRecommendation.HIGH)}
|
||||||
@ -196,8 +207,9 @@ class EPUBOutput(OutputFormatPlugin):
|
|||||||
self.workaround_ade_quirks()
|
self.workaround_ade_quirks()
|
||||||
self.workaround_webkit_quirks()
|
self.workaround_webkit_quirks()
|
||||||
self.upshift_markup()
|
self.upshift_markup()
|
||||||
|
|
||||||
from calibre.ebooks.oeb.transforms.rescale import RescaleImages
|
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
|
from calibre.ebooks.oeb.transforms.split import Split
|
||||||
split = Split(not self.opts.dont_split_on_page_breaks,
|
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
|
from calibre.ebooks.oeb.base import XPath, XHTML, barename, urlunquote
|
||||||
|
|
||||||
stylesheet = self.oeb.manifest.main_stylesheet
|
stylesheet = self.oeb.manifest.main_stylesheet
|
||||||
|
|
||||||
# ADE cries big wet tears when it encounters an invalid fragment
|
# ADE cries big wet tears when it encounters an invalid fragment
|
||||||
# identifier in the NCX toc.
|
# identifier in the NCX toc.
|
||||||
frag_pat = re.compile(r'[-A-Za-z0-9_:.]+$')
|
frag_pat = re.compile(r'[-A-Za-z0-9_:.]+$')
|
||||||
|
@ -140,7 +140,7 @@ OptionRecommendation(name='output_profile',
|
|||||||
choices=[x.short_name for x in output_profiles()],
|
choices=[x.short_name for x in output_profiles()],
|
||||||
help=_('Specify the output profile. The output profile '
|
help=_('Specify the output profile. The output profile '
|
||||||
'tells the conversion system how to optimize the '
|
'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. '
|
'an output profile can be used to optimize the output for a particular device, but this is rarely necessary. '
|
||||||
'Choices are:') + ', '.join([
|
'Choices are:') + ', '.join([
|
||||||
x.short_name for x in output_profiles()])
|
x.short_name for x in output_profiles()])
|
||||||
|
@ -15,11 +15,11 @@ class RescaleImages:
|
|||||||
def __init__(self, check_colorspaces=False):
|
def __init__(self, check_colorspaces=False):
|
||||||
self.check_colorspaces = check_colorspaces
|
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.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 PIL import Image
|
||||||
from io import BytesIO
|
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_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
|
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:
|
for item in self.oeb.manifest:
|
||||||
if item.media_type.startswith('image'):
|
if item.media_type.startswith('image'):
|
||||||
ext = item.media_type.split('/')[-1].upper()
|
ext = item.media_type.split('/')[-1].upper()
|
||||||
|
@ -14,10 +14,27 @@
|
|||||||
<string>Form</string>
|
<string>Form</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="2" column="1">
|
<item row="7" column="0">
|
||||||
<widget class="QCheckBox" name="opt_preserve_cover_aspect_ratio">
|
<widget class="QLabel" name="label_3">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Preserve cover &aspect ratio</string>
|
<string>EP&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 &cover</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QCheckBox" name="opt_epub_inline_toc">
|
||||||
|
<property name="text">
|
||||||
|
<string>Insert inline &Table of Contents</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -31,6 +48,46 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</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 &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>&Flatten EPUB file structure</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Title for inserted ToC:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>opt_toc_title</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="5" column="1">
|
<item row="5" column="1">
|
||||||
<widget class="QSpinBox" name="opt_flow_size">
|
<widget class="QSpinBox" name="opt_flow_size">
|
||||||
<property name="specialValueText">
|
<property name="specialValueText">
|
||||||
@ -50,47 +107,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</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 &cover</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QCheckBox" name="opt_no_svg_cover">
|
|
||||||
<property name="text">
|
|
||||||
<string>No &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 &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 &split on page breaks</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
<item row="3" column="1">
|
||||||
<widget class="QCheckBox" name="opt_epub_toc_at_end">
|
<widget class="QCheckBox" name="opt_epub_toc_at_end">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -98,20 +114,17 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="QCheckBox" name="opt_epub_flatten">
|
<widget class="QCheckBox" name="opt_preserve_cover_aspect_ratio">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Flatten EPUB file structure</string>
|
<string>Preserve cover &aspect ratio</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="0">
|
<item row="0" column="0" colspan="2">
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QCheckBox" name="opt_dont_split_on_page_breaks">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Title for inserted ToC:</string>
|
<string>Do not &split on page breaks</string>
|
||||||
</property>
|
|
||||||
<property name="buddy">
|
|
||||||
<cstring>opt_toc_title</cstring>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -123,17 +136,17 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="0">
|
<item row="6" column="0">
|
||||||
<widget class="QLabel" name="label_3">
|
<widget class="QLabel" name="label_4">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>EP&UB version:</string>
|
<string>Shrink &images larger than:</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="buddy">
|
<property name="buddy">
|
||||||
<cstring>opt_epub_version</cstring>
|
<cstring>opt_epub_max_image_size</cstring>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="1">
|
<item row="6" column="1">
|
||||||
<widget class="QComboBox" name="opt_epub_version"/>
|
<widget class="QLineEdit" name="opt_epub_max_image_size"/>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -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(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(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(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))
|
g.appendChild(choices('epub_version', _('EP&UB version:'), ui_data.versions))
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user