mirror of
https://github.com/ciromattia/kcc
synced 2026-04-19 07:28:55 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72f98bb032 | ||
|
|
96bf14d386 | ||
|
|
d4e1565e4a | ||
|
|
c3030e8bd1 | ||
|
|
c5744117e3 | ||
|
|
cd2eeb4d0f | ||
|
|
e7b7054b0e | ||
|
|
6f26bd5874 | ||
|
|
d5ca8fb407 |
@@ -270,7 +270,7 @@ PROCESSING:
|
|||||||
Crop empty sections. 0: Disabled 1: Horizontally 2: Both [Default=0]
|
Crop empty sections. 0: Disabled 1: Horizontally 2: Both [Default=0]
|
||||||
--blackborders Disable autodetection and force black borders
|
--blackborders Disable autodetection and force black borders
|
||||||
--whiteborders Disable autodetection and force white borders
|
--whiteborders Disable autodetection and force white borders
|
||||||
--smartcovercrop Attempt to crop main cover from wide image
|
--nosmartcovercrop Disable attempt to crop main cover from wide image
|
||||||
--coverfill Center-crop only the cover to fill target device screen
|
--coverfill Center-crop only the cover to fill target device screen
|
||||||
--forcecolor Don't convert images to grayscale
|
--forcecolor Don't convert images to grayscale
|
||||||
--forcepng Create PNG files instead JPEG for black and white images
|
--forcepng Create PNG files instead JPEG for black and white images
|
||||||
@@ -282,6 +282,7 @@ PROCESSING:
|
|||||||
--jpeg-quality The JPEG quality, on a scale from 0 (worst) to 95 (best). Default 85 for most devices.
|
--jpeg-quality The JPEG quality, on a scale from 0 (worst) to 95 (best). Default 85 for most devices.
|
||||||
--maximizestrips Turn 1x4 strips to 2x2 strips
|
--maximizestrips Turn 1x4 strips to 2x2 strips
|
||||||
-d, --delete Delete source file(s) or a directory. It's not recoverable.
|
-d, --delete Delete source file(s) or a directory. It's not recoverable.
|
||||||
|
--tempdir Create temporary files directory on source file drive.
|
||||||
|
|
||||||
OUTPUT SETTINGS:
|
OUTPUT SETTINGS:
|
||||||
-o OUTPUT, --output OUTPUT
|
-o OUTPUT, --output OUTPUT
|
||||||
|
|||||||
16
gui/KCC.ui
16
gui/KCC.ui
@@ -655,12 +655,12 @@ Higher values are larger and higher quality, and may resolve blank page issues.<
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="11" column="1">
|
<item row="11" column="1">
|
||||||
<widget class="QCheckBox" name="smartCoverCropBox">
|
<widget class="QCheckBox" name="noSmartCoverCropBox">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Attempt to crop main cover from wide image.</string>
|
<string>Disable attempt to crop main cover from wide image.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Smart Cover Crop</string>
|
<string>No Smart Cover Crop</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -885,6 +885,16 @@ Ignored for Kindle EPUB/MOBI and all PDF.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="12" column="1">
|
||||||
|
<widget class="QCheckBox" name="tempDirBox">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Unchecked - Main Drive<br/></span>Use dedicated temporary directory on main OS drive.</p><p><span style=" font-weight:600; text-decoration: underline;">Checked - Source File Drive<br/></span>Create temporary file directory on source file drive.</p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Temp Directory</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@@ -331,8 +331,8 @@ class WorkerThread(QThread):
|
|||||||
options.pdfextract = True
|
options.pdfextract = True
|
||||||
if GUI.pdfWidthBox.isChecked():
|
if GUI.pdfWidthBox.isChecked():
|
||||||
options.pdfwidth = True
|
options.pdfwidth = True
|
||||||
if GUI.smartCoverCropBox.isChecked():
|
if GUI.noSmartCoverCropBox.isChecked():
|
||||||
options.smartcovercrop = True
|
options.nosmartcovercrop = True
|
||||||
if GUI.coverFillBox.isChecked():
|
if GUI.coverFillBox.isChecked():
|
||||||
options.coverfill = True
|
options.coverfill = True
|
||||||
if GUI.metadataTitleBox.checkState() == Qt.CheckState.PartiallyChecked:
|
if GUI.metadataTitleBox.checkState() == Qt.CheckState.PartiallyChecked:
|
||||||
@@ -341,6 +341,8 @@ class WorkerThread(QThread):
|
|||||||
options.metadatatitle = 2
|
options.metadatatitle = 2
|
||||||
if GUI.deleteBox.isChecked():
|
if GUI.deleteBox.isChecked():
|
||||||
options.delete = True
|
options.delete = True
|
||||||
|
if GUI.tempDirBox.isChecked():
|
||||||
|
options.tempdir = True
|
||||||
if GUI.spreadShiftBox.isChecked():
|
if GUI.spreadShiftBox.isChecked():
|
||||||
options.spreadshift = True
|
options.spreadshift = True
|
||||||
if GUI.fileFusionBox.isChecked():
|
if GUI.fileFusionBox.isChecked():
|
||||||
@@ -1077,7 +1079,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
|
|||||||
'disableProcessingBox': GUI.disableProcessingBox.checkState(),
|
'disableProcessingBox': GUI.disableProcessingBox.checkState(),
|
||||||
'pdfExtractBox': GUI.pdfExtractBox.checkState(),
|
'pdfExtractBox': GUI.pdfExtractBox.checkState(),
|
||||||
'pdfWidthBox': GUI.pdfWidthBox.checkState(),
|
'pdfWidthBox': GUI.pdfWidthBox.checkState(),
|
||||||
'smartCoverCropBox': GUI.smartCoverCropBox.checkState(),
|
'noSmartCoverCropBox': GUI.noSmartCoverCropBox.checkState(),
|
||||||
'coverFillBox': GUI.coverFillBox.checkState(),
|
'coverFillBox': GUI.coverFillBox.checkState(),
|
||||||
'metadataTitleBox': GUI.metadataTitleBox.checkState(),
|
'metadataTitleBox': GUI.metadataTitleBox.checkState(),
|
||||||
'mozJpegBox': GUI.mozJpegBox.checkState(),
|
'mozJpegBox': GUI.mozJpegBox.checkState(),
|
||||||
@@ -1090,6 +1092,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
|
|||||||
'widthBox': GUI.widthBox.value(),
|
'widthBox': GUI.widthBox.value(),
|
||||||
'heightBox': GUI.heightBox.value(),
|
'heightBox': GUI.heightBox.value(),
|
||||||
'deleteBox': GUI.deleteBox.checkState(),
|
'deleteBox': GUI.deleteBox.checkState(),
|
||||||
|
'tempDirBox': GUI.tempDirBox.checkState(),
|
||||||
'spreadShiftBox': GUI.spreadShiftBox.checkState(),
|
'spreadShiftBox': GUI.spreadShiftBox.checkState(),
|
||||||
'fileFusionBox': GUI.fileFusionBox.checkState(),
|
'fileFusionBox': GUI.fileFusionBox.checkState(),
|
||||||
'defaultOutputFolderBox': GUI.defaultOutputFolderBox.checkState(),
|
'defaultOutputFolderBox': GUI.defaultOutputFolderBox.checkState(),
|
||||||
@@ -1257,10 +1260,10 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
|
|||||||
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': False, 'ForceColor': False, 'Label': 'KS',
|
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': False, 'ForceColor': False, 'Label': 'KS',
|
||||||
},
|
},
|
||||||
"Kindle Scribe 3": {
|
"Kindle Scribe 3": {
|
||||||
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': False, 'ForceColor': False, 'Label': 'KS3',
|
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 3, 'DefaultUpscale': False, 'ForceColor': False, 'Label': 'KS3',
|
||||||
},
|
},
|
||||||
"Kindle Scribe Colorsoft": {
|
"Kindle Scribe Colorsoft": {
|
||||||
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': False, 'ForceColor': True, 'Label': 'KSCS',
|
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 3, 'DefaultUpscale': False, 'ForceColor': True, 'Label': 'KSCS',
|
||||||
},
|
},
|
||||||
"Kindle 11": {
|
"Kindle 11": {
|
||||||
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': True, 'ForceColor': False, 'Label': 'K11',
|
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': True, 'ForceColor': False, 'Label': 'K11',
|
||||||
@@ -1269,7 +1272,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
|
|||||||
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': True, 'ForceColor': False, 'Label': 'KPW5',
|
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': True, 'ForceColor': False, 'Label': 'KPW5',
|
||||||
},
|
},
|
||||||
"Kindle Paperwhite 12": {
|
"Kindle Paperwhite 12": {
|
||||||
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': True, 'ForceColor': False, 'Label': 'KO',
|
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': True, 'ForceColor': False, 'Label': 'KPW6',
|
||||||
},
|
},
|
||||||
"Kindle Colorsoft": {
|
"Kindle Colorsoft": {
|
||||||
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': True, 'ForceColor': True, 'Label': 'KCS',
|
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': True, 'ForceColor': True, 'Label': 'KCS',
|
||||||
|
|||||||
@@ -344,10 +344,10 @@ class Ui_mainWindow(object):
|
|||||||
|
|
||||||
self.gridLayout_2.addWidget(self.metadataTitleBox, 7, 0, 1, 1)
|
self.gridLayout_2.addWidget(self.metadataTitleBox, 7, 0, 1, 1)
|
||||||
|
|
||||||
self.smartCoverCropBox = QCheckBox(self.optionWidget)
|
self.noSmartCoverCropBox = QCheckBox(self.optionWidget)
|
||||||
self.smartCoverCropBox.setObjectName(u"smartCoverCropBox")
|
self.noSmartCoverCropBox.setObjectName(u"noSmartCoverCropBox")
|
||||||
|
|
||||||
self.gridLayout_2.addWidget(self.smartCoverCropBox, 11, 1, 1, 1)
|
self.gridLayout_2.addWidget(self.noSmartCoverCropBox, 11, 1, 1, 1)
|
||||||
|
|
||||||
self.rotateFirstBox = QCheckBox(self.optionWidget)
|
self.rotateFirstBox = QCheckBox(self.optionWidget)
|
||||||
self.rotateFirstBox.setObjectName(u"rotateFirstBox")
|
self.rotateFirstBox.setObjectName(u"rotateFirstBox")
|
||||||
@@ -450,6 +450,11 @@ class Ui_mainWindow(object):
|
|||||||
|
|
||||||
self.gridLayout_2.addWidget(self.webpBox, 12, 0, 1, 1)
|
self.gridLayout_2.addWidget(self.webpBox, 12, 0, 1, 1)
|
||||||
|
|
||||||
|
self.tempDirBox = QCheckBox(self.optionWidget)
|
||||||
|
self.tempDirBox.setObjectName(u"tempDirBox")
|
||||||
|
|
||||||
|
self.gridLayout_2.addWidget(self.tempDirBox, 12, 1, 1, 1)
|
||||||
|
|
||||||
|
|
||||||
self.gridLayout.addWidget(self.optionWidget, 5, 0, 1, 2)
|
self.gridLayout.addWidget(self.optionWidget, 5, 0, 1, 2)
|
||||||
|
|
||||||
@@ -748,9 +753,9 @@ class Ui_mainWindow(object):
|
|||||||
#endif // QT_CONFIG(tooltip)
|
#endif // QT_CONFIG(tooltip)
|
||||||
self.metadataTitleBox.setText(QCoreApplication.translate("mainWindow", u"Metadata Title", None))
|
self.metadataTitleBox.setText(QCoreApplication.translate("mainWindow", u"Metadata Title", None))
|
||||||
#if QT_CONFIG(tooltip)
|
#if QT_CONFIG(tooltip)
|
||||||
self.smartCoverCropBox.setToolTip(QCoreApplication.translate("mainWindow", u"Attempt to crop main cover from wide image.", None))
|
self.noSmartCoverCropBox.setToolTip(QCoreApplication.translate("mainWindow", u"Disable attempt to crop main cover from wide image.", None))
|
||||||
#endif // QT_CONFIG(tooltip)
|
#endif // QT_CONFIG(tooltip)
|
||||||
self.smartCoverCropBox.setText(QCoreApplication.translate("mainWindow", u"Smart Cover Crop", None))
|
self.noSmartCoverCropBox.setText(QCoreApplication.translate("mainWindow", u"No Smart Cover Crop", None))
|
||||||
#if QT_CONFIG(tooltip)
|
#if QT_CONFIG(tooltip)
|
||||||
self.rotateFirstBox.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p>When the spread splitter option is partially checked,</p><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Rotate Last<br/></span>Put the rotated 2 page spread after the split spreads.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Rotate First<br/></span>Put the rotated 2 page spread before the split spreads.</p></body></html>", None))
|
self.rotateFirstBox.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p>When the spread splitter option is partially checked,</p><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Rotate Last<br/></span>Put the rotated 2 page spread after the split spreads.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Rotate First<br/></span>Put the rotated 2 page spread before the split spreads.</p></body></html>", None))
|
||||||
#endif // QT_CONFIG(tooltip)
|
#endif // QT_CONFIG(tooltip)
|
||||||
@@ -821,6 +826,10 @@ class Ui_mainWindow(object):
|
|||||||
"Ignored for Kindle EPUB/MOBI and all PDF.", None))
|
"Ignored for Kindle EPUB/MOBI and all PDF.", None))
|
||||||
#endif // QT_CONFIG(tooltip)
|
#endif // QT_CONFIG(tooltip)
|
||||||
self.webpBox.setText(QCoreApplication.translate("mainWindow", u"WebP (experimental)", None))
|
self.webpBox.setText(QCoreApplication.translate("mainWindow", u"WebP (experimental)", None))
|
||||||
|
#if QT_CONFIG(tooltip)
|
||||||
|
self.tempDirBox.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Main Drive<br/></span>Use dedicated temporary directory on main OS drive.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Source File Drive<br/></span>Create temporary file directory on source file drive.</p></body></html>", None))
|
||||||
|
#endif // QT_CONFIG(tooltip)
|
||||||
|
self.tempDirBox.setText(QCoreApplication.translate("mainWindow", u"Temp Directory", None))
|
||||||
#if QT_CONFIG(tooltip)
|
#if QT_CONFIG(tooltip)
|
||||||
self.convertButton.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p style='white-space:pre'>Shift+Click to select the output directory for this list.</p></body></html>", None))
|
self.convertButton.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p style='white-space:pre'>Shift+Click to select the output directory for this list.</p></body></html>", None))
|
||||||
#endif // QT_CONFIG(tooltip)
|
#endif // QT_CONFIG(tooltip)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
__version__ = '9.7.0'
|
__version__ = '9.7.2'
|
||||||
__license__ = 'ISC'
|
__license__ = 'ISC'
|
||||||
__copyright__ = '2012-2022, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>, darodi'
|
__copyright__ = '2012-2022, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>, darodi'
|
||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|||||||
@@ -310,6 +310,15 @@ def buildOPF(dstdir, title, filelist, originalpath, cover=None):
|
|||||||
f.writelines(["<dc:description>", hescape(options.summary), "</dc:description>\n"])
|
f.writelines(["<dc:description>", hescape(options.summary), "</dc:description>\n"])
|
||||||
for author in options.authors:
|
for author in options.authors:
|
||||||
f.writelines(["<dc:creator>", hescape(author), "</dc:creator>\n"])
|
f.writelines(["<dc:creator>", hescape(author), "</dc:creator>\n"])
|
||||||
|
if not options.iskindle and options.series:
|
||||||
|
f.writelines(['<meta property="belongs-to-collection" id="c02">', hescape(options.series), "</meta>\n"])
|
||||||
|
f.writelines(['<meta refines="#c02" property="collection-type">', "series", "</meta>\n"])
|
||||||
|
if options.volume and options.number:
|
||||||
|
f.writelines(['<meta refines="#c02" property="group-position">', hescape(f"{options.volume}.{options.number}"), "</meta>\n"])
|
||||||
|
elif options.volume:
|
||||||
|
f.writelines(['<meta refines="#c02" property="group-position">', hescape(options.volume), "</meta>\n"])
|
||||||
|
elif options.number:
|
||||||
|
f.writelines(['<meta refines="#c02" property="group-position">', hescape(options.number), "</meta>\n"])
|
||||||
f.write("<meta property=\"dcterms:modified\">" + strftime("%Y-%m-%dT%H:%M:%SZ", gmtime()) + "</meta>\n")
|
f.write("<meta property=\"dcterms:modified\">" + strftime("%Y-%m-%dT%H:%M:%SZ", gmtime()) + "</meta>\n")
|
||||||
if cover:
|
if cover:
|
||||||
f.write("<meta name=\"cover\" content=\"cover\"/>\n")
|
f.write("<meta name=\"cover\" content=\"cover\"/>\n")
|
||||||
@@ -547,7 +556,7 @@ def buildEPUB(path, chapternames, tomenumber, ischunked, cover: image.Cover, ori
|
|||||||
f.close()
|
f.close()
|
||||||
build_html_start = perf_counter()
|
build_html_start = perf_counter()
|
||||||
if cover:
|
if cover:
|
||||||
cover.save_to_epub(os.path.join(path, 'OEBPS', 'Images', 'cover.jpg'), tomenumber, len_tomes)
|
cover.save_to_folder(os.path.join(path, 'OEBPS', 'Images', 'cover.jpg'), tomenumber, len_tomes)
|
||||||
dot_clean(path)
|
dot_clean(path)
|
||||||
options.covers.append((cover, options.uuid))
|
options.covers.append((cover, options.uuid))
|
||||||
for dirpath, dirnames, filenames in os.walk(os.path.join(path, 'OEBPS', 'Images')):
|
for dirpath, dirnames, filenames in os.walk(os.path.join(path, 'OEBPS', 'Images')):
|
||||||
@@ -865,7 +874,8 @@ def mupdf_pdf_process_pages_parallel(filename, output_dir, target_width, target_
|
|||||||
def getWorkFolder(afile, workdir=None):
|
def getWorkFolder(afile, workdir=None):
|
||||||
if not workdir:
|
if not workdir:
|
||||||
workdir = mkdtemp('', 'KCC-')
|
workdir = mkdtemp('', 'KCC-')
|
||||||
# workdir = mkdtemp('', 'KCC-', os.path.dirname(afile))
|
if options.tempdir:
|
||||||
|
workdir = mkdtemp('', 'KCC-', os.path.dirname(afile))
|
||||||
fullPath = os.path.join(workdir, 'OEBPS', 'Images')
|
fullPath = os.path.join(workdir, 'OEBPS', 'Images')
|
||||||
else:
|
else:
|
||||||
fullPath = workdir
|
fullPath = workdir
|
||||||
@@ -992,6 +1002,9 @@ def getMetadata(path, originalpath):
|
|||||||
options.comicinfo_chapters = []
|
options.comicinfo_chapters = []
|
||||||
options.summary = ''
|
options.summary = ''
|
||||||
titleSuffix = ''
|
titleSuffix = ''
|
||||||
|
options.volume = ''
|
||||||
|
options.number = ''
|
||||||
|
options.series = ''
|
||||||
if options.title == 'defaulttitle':
|
if options.title == 'defaulttitle':
|
||||||
defaultTitle = True
|
defaultTitle = True
|
||||||
if os.path.isdir(originalpath):
|
if os.path.isdir(originalpath):
|
||||||
@@ -1020,8 +1033,10 @@ def getMetadata(path, originalpath):
|
|||||||
options.title = xml.data['Series']
|
options.title = xml.data['Series']
|
||||||
if xml.data['Volume']:
|
if xml.data['Volume']:
|
||||||
titleSuffix += ' Vol. ' + xml.data['Volume'].zfill(2)
|
titleSuffix += ' Vol. ' + xml.data['Volume'].zfill(2)
|
||||||
|
options.volume = xml.data['Volume']
|
||||||
if xml.data['Number']:
|
if xml.data['Number']:
|
||||||
titleSuffix += ' #' + xml.data['Number'].zfill(3)
|
titleSuffix += ' #' + xml.data['Number'].zfill(3)
|
||||||
|
options.number = xml.data['Number']
|
||||||
if options.metadatatitle == 1 and xml.data['Title']:
|
if options.metadatatitle == 1 and xml.data['Title']:
|
||||||
titleSuffix += ': ' + xml.data['Title']
|
titleSuffix += ': ' + xml.data['Title']
|
||||||
options.title += titleSuffix
|
options.title += titleSuffix
|
||||||
@@ -1039,6 +1054,8 @@ def getMetadata(path, originalpath):
|
|||||||
options.comicinfo_chapters = xml.data['Bookmarks']
|
options.comicinfo_chapters = xml.data['Bookmarks']
|
||||||
if xml.data['Summary']:
|
if xml.data['Summary']:
|
||||||
options.summary = xml.data['Summary']
|
options.summary = xml.data['Summary']
|
||||||
|
if xml.data['Series']:
|
||||||
|
options.series = xml.data['Series']
|
||||||
os.remove(xmlPath)
|
os.remove(xmlPath)
|
||||||
|
|
||||||
if originalpath.lower().endswith('.pdf'):
|
if originalpath.lower().endswith('.pdf'):
|
||||||
@@ -1378,8 +1395,8 @@ def makeParser():
|
|||||||
help="Use the legacy PDF image extraction method from KCC 8 and earlier")
|
help="Use the legacy PDF image extraction method from KCC 8 and earlier")
|
||||||
processing_options.add_argument("--pdfwidth", action="store_true", dest="pdfwidth", default=False,
|
processing_options.add_argument("--pdfwidth", action="store_true", dest="pdfwidth", default=False,
|
||||||
help="Render vector PDFs to device width instead of height.")
|
help="Render vector PDFs to device width instead of height.")
|
||||||
processing_options.add_argument("--smartcovercrop", action="store_true", dest="smartcovercrop", default=False,
|
processing_options.add_argument("--nosmartcovercrop", action="store_true", dest="nosmartcovercrop", default=False,
|
||||||
help="Attempt to crop main cover from wide image")
|
help="Disable attempt to crop main cover from wide image")
|
||||||
processing_options.add_argument("--coverfill", action="store_true", dest="coverfill", default=False,
|
processing_options.add_argument("--coverfill", action="store_true", dest="coverfill", default=False,
|
||||||
help="Crop cover to fill screen")
|
help="Crop cover to fill screen")
|
||||||
processing_options.add_argument("-u", "--upscale", action="store_true", dest="upscale", default=False,
|
processing_options.add_argument("-u", "--upscale", action="store_true", dest="upscale", default=False,
|
||||||
@@ -1434,6 +1451,8 @@ def makeParser():
|
|||||||
help="Turn 1x4 strips to 2x2 strips")
|
help="Turn 1x4 strips to 2x2 strips")
|
||||||
processing_options.add_argument("-d", "--delete", action="store_true", dest="delete", default=False,
|
processing_options.add_argument("-d", "--delete", action="store_true", dest="delete", default=False,
|
||||||
help="Delete source file(s) or a directory. It's not recoverable.")
|
help="Delete source file(s) or a directory. It's not recoverable.")
|
||||||
|
processing_options.add_argument("--tempdir", action="store_true", dest="tempdir", default=False,
|
||||||
|
help="Create temporary files directory on source file drive.")
|
||||||
|
|
||||||
custom_profile_options.add_argument("--customwidth", type=int, dest="customwidth", default=0,
|
custom_profile_options.add_argument("--customwidth", type=int, dest="customwidth", default=0,
|
||||||
help="Replace screen width provided by device profile")
|
help="Replace screen width provided by device profile")
|
||||||
@@ -1696,12 +1715,16 @@ def makeBook(source, qtgui=None, job_progress=''):
|
|||||||
filepath.append(getOutputFilename(source, options.output, '.cbz', ' ' + str(tomeNumber)))
|
filepath.append(getOutputFilename(source, options.output, '.cbz', ' ' + str(tomeNumber)))
|
||||||
else:
|
else:
|
||||||
filepath.append(getOutputFilename(source, options.output, '.cbz', ''))
|
filepath.append(getOutputFilename(source, options.output, '.cbz', ''))
|
||||||
|
if cover.smartcover:
|
||||||
|
cover.save_to_folder(os.path.join(tome, 'OEBPS', 'Images', 'cover.jpg'), tomeNumber, len(tomes))
|
||||||
makeZIP(tome + '_comic', os.path.join(tome, "OEBPS", "Images"), job_progress)
|
makeZIP(tome + '_comic', os.path.join(tome, "OEBPS", "Images"), job_progress)
|
||||||
elif options.format == 'PDF':
|
elif options.format == 'PDF':
|
||||||
print(f"{job_progress}Creating PDF file with PyMuPDF...")
|
print(f"{job_progress}Creating PDF file with PyMuPDF...")
|
||||||
# determine output filename based on source and tome count
|
# determine output filename based on source and tome count
|
||||||
suffix = (' ' + str(tomeNumber)) if len(tomes) > 1 else ''
|
suffix = (' ' + str(tomeNumber)) if len(tomes) > 1 else ''
|
||||||
output_file = getOutputFilename(source, options.output, '.pdf', suffix)
|
output_file = getOutputFilename(source, options.output, '.pdf', suffix)
|
||||||
|
if cover.smartcover:
|
||||||
|
cover.save_to_folder(os.path.join(tome, 'OEBPS', 'Images', 'cover.jpg'), tomeNumber, len(tomes))
|
||||||
# use optimized buildPDF logic with streaming and compression
|
# use optimized buildPDF logic with streaming and compression
|
||||||
output_pdf = buildPDF(tome, options.title, job_progress, None, output_file)
|
output_pdf = buildPDF(tome, options.title, job_progress, None, output_file)
|
||||||
filepath.append(output_pdf)
|
filepath.append(output_pdf)
|
||||||
|
|||||||
@@ -98,14 +98,15 @@ class ProfileData:
|
|||||||
'KV': ("Kindle Voyage", (1072, 1448), Palette16, 1.0),
|
'KV': ("Kindle Voyage", (1072, 1448), Palette16, 1.0),
|
||||||
'KPW34': ("Kindle Paperwhite 3/4/Oasis", (1072, 1448), Palette16, 1.0),
|
'KPW34': ("Kindle Paperwhite 3/4/Oasis", (1072, 1448), Palette16, 1.0),
|
||||||
'K810': ("Kindle 8/10", (600, 800), Palette16, 1.0),
|
'K810': ("Kindle 8/10", (600, 800), Palette16, 1.0),
|
||||||
'KO': ("Kindle Oasis 2/3/Paperwhite 12", (1264, 1680), Palette16, 1.0),
|
'KO': ("Kindle Oasis 2/3", (1264, 1680), Palette16, 1.0),
|
||||||
'K11': ("Kindle 11", (1072, 1448), Palette16, 1.0),
|
'K11': ("Kindle 11", (1072, 1448), Palette16, 1.0),
|
||||||
'KPW5': ("Kindle Paperwhite 5/Signature Edition", (1236, 1648), Palette16, 1.0),
|
'KPW5': ("Kindle Paperwhite 5/Signature Edition", (1236, 1648), Palette16, 1.0),
|
||||||
|
'KPW6': ("Kindle Paperwhite 6", (1272, 1696), Palette16, 1.0),
|
||||||
'KS1860': ("Kindle 1860", (1860, 1920), Palette16, 1.0),
|
'KS1860': ("Kindle 1860", (1860, 1920), Palette16, 1.0),
|
||||||
'KS1920': ("Kindle 1920", (1920, 1920), Palette16, 1.0),
|
'KS1920': ("Kindle 1920", (1920, 1920), Palette16, 1.0),
|
||||||
'KS1240': ("Kindle 1240", (1240, 1860), Palette16, 1.0),
|
'KS1240': ("Kindle 1240", (1240, 1860), Palette16, 1.0),
|
||||||
'KS': ("Kindle Scribe 1/2", (1860, 2480), Palette16, 1.0),
|
'KS': ("Kindle Scribe 1/2", (1860, 2480), Palette16, 1.0),
|
||||||
'KCS': ("Kindle Colorsoft", (1264, 1680), Palette16, 1.0),
|
'KCS': ("Kindle Colorsoft", (1272, 1696), Palette16, 1.0),
|
||||||
'KS3': ("Kindle Scribe 3", (1986, 2648), Palette16, 1.0),
|
'KS3': ("Kindle Scribe 3", (1986, 2648), Palette16, 1.0),
|
||||||
'KSCS': ("Kindle Scribe Colorsoft", (1986, 2648), Palette16, 1.0),
|
'KSCS': ("Kindle Scribe Colorsoft", (1986, 2648), Palette16, 1.0),
|
||||||
}
|
}
|
||||||
@@ -203,7 +204,7 @@ class ComicPageParser:
|
|||||||
spread = spread.rotate(-90, Image.Resampling.BICUBIC, True)
|
spread = spread.rotate(-90, Image.Resampling.BICUBIC, True)
|
||||||
self.payload.append(['R', self.source, spread, self.fill])
|
self.payload.append(['R', self.source, spread, self.fill])
|
||||||
elif (width > height) != (dstwidth > dstheight) and not self.opt.webtoon:
|
elif (width > height) != (dstwidth > dstheight) and not self.opt.webtoon:
|
||||||
if self.opt.splitter != 1:
|
if self.opt.splitter != 1 and width / height < 2:
|
||||||
if width > height:
|
if width > height:
|
||||||
leftbox = (0, 0, int(width / 2), height)
|
leftbox = (0, 0, int(width / 2), height)
|
||||||
rightbox = (int(width / 2), 0, width, height)
|
rightbox = (int(width / 2), 0, width, height)
|
||||||
@@ -218,7 +219,7 @@ class ComicPageParser:
|
|||||||
pagetwo = self.image.crop(rightbox)
|
pagetwo = self.image.crop(rightbox)
|
||||||
self.payload.append(['S1', self.source, pageone, self.fill])
|
self.payload.append(['S1', self.source, pageone, self.fill])
|
||||||
self.payload.append(['S2', self.source, pagetwo, self.fill])
|
self.payload.append(['S2', self.source, pagetwo, self.fill])
|
||||||
if self.opt.splitter > 0:
|
if self.opt.splitter > 0 or (self.opt.splitter == 0 and width / height >= 2):
|
||||||
spread = self.image
|
spread = self.image
|
||||||
if not self.opt.norotate:
|
if not self.opt.norotate:
|
||||||
if not self.opt.rotateright:
|
if not self.opt.rotateright:
|
||||||
@@ -569,6 +570,7 @@ class Cover:
|
|||||||
self.options = opt
|
self.options = opt
|
||||||
self.source = source
|
self.source = source
|
||||||
self.image = Image.open(source)
|
self.image = Image.open(source)
|
||||||
|
self.smartcover = False
|
||||||
# backwards compatibility for Pillow >9.1.0
|
# backwards compatibility for Pillow >9.1.0
|
||||||
if not hasattr(Image, 'Resampling'):
|
if not hasattr(Image, 'Resampling'):
|
||||||
Image.Resampling = Image
|
Image.Resampling = Image
|
||||||
@@ -579,7 +581,7 @@ class Cover:
|
|||||||
self.image = ImageOps.autocontrast(self.image, preserve_tone=True)
|
self.image = ImageOps.autocontrast(self.image, preserve_tone=True)
|
||||||
if not self.options.forcecolor:
|
if not self.options.forcecolor:
|
||||||
self.image = self.image.convert('L')
|
self.image = self.image.convert('L')
|
||||||
if self.options.smartcovercrop:
|
if not self.options.nosmartcovercrop:
|
||||||
self.crop_main_cover()
|
self.crop_main_cover()
|
||||||
|
|
||||||
size = list(self.options.profileData[1])
|
size = list(self.options.profileData[1])
|
||||||
@@ -595,17 +597,19 @@ class Cover:
|
|||||||
def crop_main_cover(self):
|
def crop_main_cover(self):
|
||||||
w, h = self.image.size
|
w, h = self.image.size
|
||||||
if w / h > 2:
|
if w / h > 2:
|
||||||
|
self.smartcover = True
|
||||||
if self.options.righttoleft:
|
if self.options.righttoleft:
|
||||||
self.image = self.image.crop((w/6, 0, w/2 - w * 0.02, h))
|
self.image = self.image.crop((w/6, 0, w/2 - w * 0.02, h))
|
||||||
else:
|
else:
|
||||||
self.image = self.image.crop((w/2 + w * 0.02, 0, 5/6 * w, h))
|
self.image = self.image.crop((w/2 + w * 0.02, 0, 5/6 * w, h))
|
||||||
elif w / h > 1.34:
|
elif w / h > 1.34:
|
||||||
|
self.smartcover = True
|
||||||
if self.options.righttoleft:
|
if self.options.righttoleft:
|
||||||
self.image = self.image.crop((0, 0, w/2 - w * 0.03, h))
|
self.image = self.image.crop((0, 0, w/2 - w * 0.03, h))
|
||||||
else:
|
else:
|
||||||
self.image = self.image.crop((w/2 + w * 0.03, 0, w, h))
|
self.image = self.image.crop((w/2 + w * 0.03, 0, w, h))
|
||||||
|
|
||||||
def save_to_epub(self, target, tomeid, len_tomes=0):
|
def save_to_folder(self, target, tomeid, len_tomes=0):
|
||||||
try:
|
try:
|
||||||
if tomeid == 0:
|
if tomeid == 0:
|
||||||
self.image.save(target, "JPEG", optimize=1, quality=self.options.jpegquality)
|
self.image.save(target, "JPEG", optimize=1, quality=self.options.jpegquality)
|
||||||
|
|||||||
Reference in New Issue
Block a user