mirror of
https://github.com/ciromattia/kcc
synced 2026-04-15 13:38:46 +00:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa5f4991dd | ||
|
|
f9064ef0e4 | ||
|
|
e14abe1787 | ||
|
|
c58387f4f4 | ||
|
|
9b63b7af2c | ||
|
|
f74e108a3e | ||
|
|
f088ad732e | ||
|
|
8e5d57364d | ||
|
|
b767d5dc2c | ||
|
|
7228055bca | ||
|
|
8c57fbf318 | ||
|
|
7e94861fa1 | ||
|
|
9992ca4d26 | ||
|
|
f47d1427f0 | ||
|
|
ce8998375c | ||
|
|
8870898a87 | ||
|
|
a017cfd00d | ||
|
|
3f4ef3e21e | ||
|
|
4733c6348b | ||
|
|
5ad23d9629 |
2
.github/workflows/package-linux.yml
vendored
2
.github/workflows/package-linux.yml
vendored
@@ -59,7 +59,7 @@ jobs:
|
||||
env:
|
||||
UPDATE_INFO: gh-releases-zsync|ciromattia|kcc|latest|*x86_64.AppImage.zsync
|
||||
- name: upload artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: AppImage
|
||||
path: './*.AppImage*'
|
||||
|
||||
4
.github/workflows/package-macos.yml
vendored
4
.github/workflows/package-macos.yml
vendored
@@ -27,6 +27,8 @@ jobs:
|
||||
matrix:
|
||||
os: [ macos-15-intel, macos-14 ]
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
MACOSX_DEPLOYMENT_TARGET: '14.0'
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Set up Python
|
||||
@@ -78,7 +80,7 @@ jobs:
|
||||
run: |
|
||||
python setup.py build_binary
|
||||
- name: upload build
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: mac-os-build-${{ runner.arch }}
|
||||
path: dist/*.dmg
|
||||
|
||||
2
.github/workflows/package-osx-legacy.yml
vendored
2
.github/workflows/package-osx-legacy.yml
vendored
@@ -51,7 +51,7 @@ jobs:
|
||||
run: |
|
||||
python3 setup.py build_binary
|
||||
- name: upload build
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: osx-build-${{ runner.arch }}
|
||||
path: dist/*.dmg
|
||||
|
||||
2
.github/workflows/package-windows.yml
vendored
2
.github/workflows/package-windows.yml
vendored
@@ -53,7 +53,7 @@ jobs:
|
||||
python setup.py ${{ matrix.command }}
|
||||
- name: upload-unsigned-artifact
|
||||
id: upload-unsigned-artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: windows-build-${{ matrix.entry }}
|
||||
path: dist/*.exe
|
||||
|
||||
2
.github/workflows/package-windows7.yml
vendored
2
.github/workflows/package-windows7.yml
vendored
@@ -46,7 +46,7 @@ jobs:
|
||||
python setup.py build_binary
|
||||
- name: upload-unsigned-artifact
|
||||
id: upload-unsigned-artifact
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: windows7-build
|
||||
path: dist/*.exe
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
[](https://github.com/ciromattia/kcc/releases)
|
||||
|
||||
|
||||
**Kindle Comic Converter** optimizes black & white comics and manga for E-ink ereaders
|
||||
**Kindle Comic Converter** optimizes black & white (or color) comics and manga for E-ink ereaders
|
||||
like Kindle, Kobo, ReMarkable, and more.
|
||||
Pages display in fullscreen without margins,
|
||||
with proper fixed layout support.
|
||||
@@ -92,7 +92,7 @@ Click on **Assets** of the latest release.
|
||||
You probably want either
|
||||
- `KCC_*.*.*.exe` (Windows)
|
||||
- `kcc_macos_arm_*.*.*.dmg` (recent Mac with Apple Silicon M1 chip or later)
|
||||
- `kcc_macos_i386_*.*.*.dmg` (older Mac with Intel chip macOS 12+)
|
||||
- `kcc_macos_i386_*.*.*.dmg` (older Mac with Intel chip macOS 14+)
|
||||
|
||||
There are also legacy macOS 10.14+ and Windows 7 experimental versions available.
|
||||
|
||||
@@ -255,6 +255,7 @@ PROCESSING:
|
||||
--forcecolor Don't convert images to grayscale
|
||||
--forcepng Create PNG files instead JPEG
|
||||
--mozjpeg Create JPEG files using mozJpeg
|
||||
--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
|
||||
-d, --delete Delete source file(s) or a directory. It's not recoverable.
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
name: kcc
|
||||
channels:
|
||||
- conda-forge
|
||||
- defaults
|
||||
dependencies:
|
||||
- python=3.11
|
||||
- Pillow>=11.3.0
|
||||
- psutil>=5.9.5
|
||||
- python-slugify>=1.2.1
|
||||
- raven>=6.0.0
|
||||
- distro
|
||||
- natsort>=8.4.0
|
||||
- pip
|
||||
- pip:
|
||||
- mozjpeg-lossless-optimization>=1.1.2
|
||||
- pyside6>=6.5.1
|
||||
1011
gui/KCC.ui
1011
gui/KCC.ui
File diff suppressed because it is too large
Load Diff
@@ -22,7 +22,7 @@ import itertools
|
||||
from pathlib import Path
|
||||
from PySide6.QtCore import (QSize, QUrl, Qt, Signal, QIODeviceBase, QEvent, QThread, QSettings)
|
||||
from PySide6.QtGui import (QColor, QIcon, QPixmap, QDesktopServices)
|
||||
from PySide6.QtWidgets import (QApplication, QLabel, QListWidgetItem, QMainWindow, QSystemTrayIcon, QFileDialog, QMessageBox, QDialog)
|
||||
from PySide6.QtWidgets import (QApplication, QLabel, QListWidgetItem, QMainWindow, QSystemTrayIcon, QFileDialog, QMessageBox, QDialog, QTreeView, QAbstractItemView)
|
||||
from PySide6.QtNetwork import (QLocalSocket, QLocalServer)
|
||||
|
||||
import os
|
||||
@@ -347,6 +347,8 @@ class WorkerThread(QThread):
|
||||
options.forcepng = True
|
||||
elif GUI.mozJpegBox.checkState() == Qt.CheckState.Checked:
|
||||
options.mozjpeg = True
|
||||
if GUI.jpegQualityBox.isChecked():
|
||||
options.jpegquality = GUI.jpegQualitySpinBox.value()
|
||||
if GUI.currentMode > 2:
|
||||
options.customwidth = str(GUI.widthBox.value())
|
||||
options.customheight = str(GUI.heightBox.value())
|
||||
@@ -610,12 +612,30 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
|
||||
'Comic (*.pdf);;All (*.*)')
|
||||
for fname in fnames[0]:
|
||||
if fname != '':
|
||||
if sys.platform.startswith('win'):
|
||||
fname = fname.replace('/', '\\')
|
||||
self.lastPath = os.path.abspath(os.path.join(fname, os.pardir))
|
||||
GUI.jobList.addItem(fname)
|
||||
GUI.jobList.scrollToBottom()
|
||||
|
||||
def selectDir(self):
|
||||
if self.needClean:
|
||||
self.needClean = False
|
||||
GUI.jobList.clear()
|
||||
|
||||
dialog = QFileDialog(MW, 'Select input folder(s)', self.lastPath)
|
||||
dialog.setFileMode(QFileDialog.FileMode.Directory)
|
||||
dialog.setOption(QFileDialog.Option.ShowDirsOnly, True)
|
||||
dialog.setOption(QFileDialog.Option.DontUseNativeDialog, True)
|
||||
dialog.findChild(QTreeView).setSelectionMode(QAbstractItemView.ExtendedSelection)
|
||||
|
||||
if dialog.exec():
|
||||
dnames = dialog.selectedFiles()
|
||||
for dname in dnames:
|
||||
if dname != '':
|
||||
self.lastPath = os.path.abspath(os.path.join(dname, os.pardir))
|
||||
GUI.jobList.addItem(dname)
|
||||
GUI.jobList.scrollToBottom()
|
||||
|
||||
|
||||
def selectFileMetaEditor(self, sname):
|
||||
if not sname:
|
||||
if QApplication.keyboardModifiers() == Qt.ShiftModifier:
|
||||
@@ -724,6 +744,12 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
|
||||
GUI.croppingWidget.setVisible(False)
|
||||
self.changeCroppingPower(100) # 1.0
|
||||
|
||||
def togglejpegqualityBox(self, value):
|
||||
if value:
|
||||
GUI.jpegQualityWidget.setVisible(True)
|
||||
else:
|
||||
GUI.jpegQualityWidget.setVisible(False)
|
||||
|
||||
def togglewebtoonBox(self, value):
|
||||
if value:
|
||||
self.addMessage('You can choose a taller device profile to get taller cuts in webtoon mode.', 'info')
|
||||
@@ -754,7 +780,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
|
||||
GUI.rotateBox.setEnabled(True)
|
||||
GUI.borderBox.setEnabled(True)
|
||||
profile = GUI.profiles[str(GUI.deviceBox.currentText())]
|
||||
if profile['Label'] != 'KS':
|
||||
if not profile['Label'].startswith('KS'):
|
||||
GUI.upscaleBox.setEnabled(True)
|
||||
GUI.croppingBox.setEnabled(True)
|
||||
GUI.interPanelCropBox.setEnabled(True)
|
||||
@@ -779,7 +805,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
|
||||
def toggleImageFormatBox(self, value):
|
||||
profile = GUI.profiles[str(GUI.deviceBox.currentText())]
|
||||
if value == 1:
|
||||
if profile['Label'] == 'KS':
|
||||
if profile['Label'].startswith('KS'):
|
||||
current_format = GUI.formats[str(GUI.formatBox.currentText())]['format']
|
||||
for bad_format in ('MOBI', 'EPUB'):
|
||||
if bad_format in current_format:
|
||||
@@ -841,7 +867,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
|
||||
if not GUI.webtoonBox.isChecked():
|
||||
GUI.qualityBox.setEnabled(profile['PVOptions'])
|
||||
GUI.upscaleBox.setChecked(profile['DefaultUpscale'])
|
||||
if profile['Label'] == 'KS':
|
||||
if profile['Label'].startswith('KS'):
|
||||
GUI.upscaleBox.setDisabled(True)
|
||||
else:
|
||||
if not GUI.webtoonBox.isChecked():
|
||||
@@ -1008,6 +1034,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
|
||||
'disableProcessingBox': GUI.disableProcessingBox.checkState(),
|
||||
'metadataTitleBox': GUI.metadataTitleBox.checkState(),
|
||||
'mozJpegBox': GUI.mozJpegBox.checkState(),
|
||||
'jpegQualityBox': GUI.jpegQualityBox.checkState(),
|
||||
'widthBox': GUI.widthBox.value(),
|
||||
'heightBox': GUI.heightBox.value(),
|
||||
'deleteBox': GUI.deleteBox.checkState(),
|
||||
@@ -1162,9 +1189,15 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
|
||||
'DefaultUpscale': True, 'ForceColor': False, 'Label': 'KPW34'},
|
||||
"Kindle Voyage": {'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0,
|
||||
'DefaultUpscale': True, 'ForceColor': False, 'Label': 'KV'},
|
||||
"Kindle Scribe": {
|
||||
"Kindle Scribe 1/2": {
|
||||
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': False, 'ForceColor': False, 'Label': 'KS',
|
||||
},
|
||||
"Kindle Scribe 3": {
|
||||
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': False, 'ForceColor': False, 'Label': 'KS3',
|
||||
},
|
||||
"Kindle Scribe Colorsoft": {
|
||||
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': False, 'ForceColor': True, 'Label': 'KSCS',
|
||||
},
|
||||
"Kindle 11": {
|
||||
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': True, 'ForceColor': False, 'Label': 'K11',
|
||||
},
|
||||
@@ -1239,9 +1272,11 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
|
||||
'Label': 'OTHER'},
|
||||
}
|
||||
profilesGUI = [
|
||||
"Kindle Scribe Colorsoft",
|
||||
"Kindle Scribe 3",
|
||||
"Kindle Colorsoft",
|
||||
"Kindle Paperwhite 12",
|
||||
"Kindle Scribe",
|
||||
"Kindle Scribe 1/2",
|
||||
"Kindle Paperwhite 11",
|
||||
"Kindle 11",
|
||||
"Kindle Oasis 9/10",
|
||||
@@ -1319,6 +1354,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
|
||||
GUI.defaultOutputFolderButton.clicked.connect(self.selectDefaultOutputFolder)
|
||||
GUI.clearButton.clicked.connect(self.clearJobs)
|
||||
GUI.fileButton.clicked.connect(self.selectFile)
|
||||
GUI.directoryButton.clicked.connect(self.selectDir)
|
||||
GUI.editorButton.clicked.connect(self.selectFileMetaEditor)
|
||||
GUI.wikiButton.clicked.connect(self.openWiki)
|
||||
GUI.kofiButton.clicked.connect(self.openKofi)
|
||||
@@ -1327,6 +1363,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
|
||||
GUI.gammaBox.stateChanged.connect(self.togglegammaBox)
|
||||
GUI.croppingBox.stateChanged.connect(self.togglecroppingBox)
|
||||
GUI.croppingPowerSlider.valueChanged.connect(self.changeCroppingPower)
|
||||
GUI.jpegQualityBox.stateChanged.connect(self.togglejpegqualityBox)
|
||||
GUI.webtoonBox.stateChanged.connect(self.togglewebtoonBox)
|
||||
GUI.qualityBox.stateChanged.connect(self.togglequalityBox)
|
||||
GUI.mozJpegBox.stateChanged.connect(self.toggleImageFormatBox)
|
||||
|
||||
@@ -26,7 +26,7 @@ class Ui_mainWindow(object):
|
||||
def setupUi(self, mainWindow):
|
||||
if not mainWindow.objectName():
|
||||
mainWindow.setObjectName(u"mainWindow")
|
||||
mainWindow.resize(566, 573)
|
||||
mainWindow.resize(566, 658)
|
||||
icon = QIcon()
|
||||
icon.addFile(u":/Icon/icons/comic2ebook.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
mainWindow.setWindowIcon(icon)
|
||||
@@ -35,6 +35,253 @@ class Ui_mainWindow(object):
|
||||
self.gridLayout = QGridLayout(self.centralWidget)
|
||||
self.gridLayout.setObjectName(u"gridLayout")
|
||||
self.gridLayout.setContentsMargins(-1, -1, -1, 5)
|
||||
self.progressBar = QProgressBar(self.centralWidget)
|
||||
self.progressBar.setObjectName(u"progressBar")
|
||||
self.progressBar.setMinimumSize(QSize(0, 30))
|
||||
font = QFont()
|
||||
font.setBold(True)
|
||||
self.progressBar.setFont(font)
|
||||
self.progressBar.setVisible(False)
|
||||
self.progressBar.setAlignment(Qt.AlignmentFlag.AlignJustify|Qt.AlignmentFlag.AlignVCenter)
|
||||
|
||||
self.gridLayout.addWidget(self.progressBar, 1, 0, 1, 2)
|
||||
|
||||
self.toolWidget = QWidget(self.centralWidget)
|
||||
self.toolWidget.setObjectName(u"toolWidget")
|
||||
self.horizontalLayout = QHBoxLayout(self.toolWidget)
|
||||
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
||||
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.editorButton = QPushButton(self.toolWidget)
|
||||
self.editorButton.setObjectName(u"editorButton")
|
||||
self.editorButton.setMinimumSize(QSize(0, 30))
|
||||
icon1 = QIcon()
|
||||
icon1.addFile(u":/Other/icons/editor.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.editorButton.setIcon(icon1)
|
||||
|
||||
self.horizontalLayout.addWidget(self.editorButton)
|
||||
|
||||
self.kofiButton = QPushButton(self.toolWidget)
|
||||
self.kofiButton.setObjectName(u"kofiButton")
|
||||
self.kofiButton.setMinimumSize(QSize(0, 30))
|
||||
icon2 = QIcon()
|
||||
icon2.addFile(u":/Brand/icons/kofi_symbol.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.kofiButton.setIcon(icon2)
|
||||
self.kofiButton.setIconSize(QSize(19, 16))
|
||||
|
||||
self.horizontalLayout.addWidget(self.kofiButton)
|
||||
|
||||
self.wikiButton = QPushButton(self.toolWidget)
|
||||
self.wikiButton.setObjectName(u"wikiButton")
|
||||
self.wikiButton.setMinimumSize(QSize(0, 30))
|
||||
icon3 = QIcon()
|
||||
icon3.addFile(u":/Other/icons/wiki.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.wikiButton.setIcon(icon3)
|
||||
|
||||
self.horizontalLayout.addWidget(self.wikiButton)
|
||||
|
||||
|
||||
self.gridLayout.addWidget(self.toolWidget, 0, 0, 1, 2)
|
||||
|
||||
self.croppingWidget = QWidget(self.centralWidget)
|
||||
self.croppingWidget.setObjectName(u"croppingWidget")
|
||||
self.croppingWidget.setVisible(False)
|
||||
self.gridLayout_5 = QGridLayout(self.croppingWidget)
|
||||
self.gridLayout_5.setObjectName(u"gridLayout_5")
|
||||
self.gridLayout_5.setContentsMargins(0, 0, 0, 0)
|
||||
self.croppingPowerSlider = QSlider(self.croppingWidget)
|
||||
self.croppingPowerSlider.setObjectName(u"croppingPowerSlider")
|
||||
self.croppingPowerSlider.setMaximum(300)
|
||||
self.croppingPowerSlider.setSingleStep(1)
|
||||
self.croppingPowerSlider.setOrientation(Qt.Orientation.Horizontal)
|
||||
|
||||
self.gridLayout_5.addWidget(self.croppingPowerSlider, 0, 1, 1, 1)
|
||||
|
||||
self.preserveMarginBox = QSpinBox(self.croppingWidget)
|
||||
self.preserveMarginBox.setObjectName(u"preserveMarginBox")
|
||||
sizePolicy = QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.preserveMarginBox.sizePolicy().hasHeightForWidth())
|
||||
self.preserveMarginBox.setSizePolicy(sizePolicy)
|
||||
self.preserveMarginBox.setMaximum(99)
|
||||
self.preserveMarginBox.setSingleStep(5)
|
||||
self.preserveMarginBox.setValue(0)
|
||||
|
||||
self.gridLayout_5.addWidget(self.preserveMarginBox, 1, 1, 1, 1)
|
||||
|
||||
self.preserveMarginLabel = QLabel(self.croppingWidget)
|
||||
self.preserveMarginLabel.setObjectName(u"preserveMarginLabel")
|
||||
|
||||
self.gridLayout_5.addWidget(self.preserveMarginLabel, 1, 0, 1, 1)
|
||||
|
||||
self.croppingPowerLabel = QLabel(self.croppingWidget)
|
||||
self.croppingPowerLabel.setObjectName(u"croppingPowerLabel")
|
||||
|
||||
self.gridLayout_5.addWidget(self.croppingPowerLabel, 0, 0, 1, 1)
|
||||
|
||||
|
||||
self.gridLayout.addWidget(self.croppingWidget, 9, 0, 1, 2)
|
||||
|
||||
self.customWidget = QWidget(self.centralWidget)
|
||||
self.customWidget.setObjectName(u"customWidget")
|
||||
self.customWidget.setVisible(False)
|
||||
self.gridLayout_3 = QGridLayout(self.customWidget)
|
||||
self.gridLayout_3.setObjectName(u"gridLayout_3")
|
||||
self.gridLayout_3.setContentsMargins(0, 0, 0, 0)
|
||||
self.hLabel = QLabel(self.customWidget)
|
||||
self.hLabel.setObjectName(u"hLabel")
|
||||
sizePolicy1 = QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Preferred)
|
||||
sizePolicy1.setHorizontalStretch(0)
|
||||
sizePolicy1.setVerticalStretch(0)
|
||||
sizePolicy1.setHeightForWidth(self.hLabel.sizePolicy().hasHeightForWidth())
|
||||
self.hLabel.setSizePolicy(sizePolicy1)
|
||||
|
||||
self.gridLayout_3.addWidget(self.hLabel, 0, 2, 1, 1)
|
||||
|
||||
self.widthBox = QSpinBox(self.customWidget)
|
||||
self.widthBox.setObjectName(u"widthBox")
|
||||
self.widthBox.setMaximum(6000)
|
||||
|
||||
self.gridLayout_3.addWidget(self.widthBox, 0, 1, 1, 1)
|
||||
|
||||
self.wLabel = QLabel(self.customWidget)
|
||||
self.wLabel.setObjectName(u"wLabel")
|
||||
sizePolicy1.setHeightForWidth(self.wLabel.sizePolicy().hasHeightForWidth())
|
||||
self.wLabel.setSizePolicy(sizePolicy1)
|
||||
|
||||
self.gridLayout_3.addWidget(self.wLabel, 0, 0, 1, 1)
|
||||
|
||||
self.heightBox = QSpinBox(self.customWidget)
|
||||
self.heightBox.setObjectName(u"heightBox")
|
||||
self.heightBox.setMaximum(8000)
|
||||
|
||||
self.gridLayout_3.addWidget(self.heightBox, 0, 3, 1, 1)
|
||||
|
||||
|
||||
self.gridLayout.addWidget(self.customWidget, 8, 0, 1, 2)
|
||||
|
||||
self.buttonWidget = QWidget(self.centralWidget)
|
||||
self.buttonWidget.setObjectName(u"buttonWidget")
|
||||
sizePolicy2 = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
|
||||
sizePolicy2.setHorizontalStretch(0)
|
||||
sizePolicy2.setVerticalStretch(0)
|
||||
sizePolicy2.setHeightForWidth(self.buttonWidget.sizePolicy().hasHeightForWidth())
|
||||
self.buttonWidget.setSizePolicy(sizePolicy2)
|
||||
self.gridLayout_4 = QGridLayout(self.buttonWidget)
|
||||
self.gridLayout_4.setObjectName(u"gridLayout_4")
|
||||
self.gridLayout_4.setContentsMargins(0, 0, 0, 0)
|
||||
self.convertButton = QPushButton(self.buttonWidget)
|
||||
self.convertButton.setObjectName(u"convertButton")
|
||||
self.convertButton.setMinimumSize(QSize(0, 30))
|
||||
self.convertButton.setFont(font)
|
||||
icon4 = QIcon()
|
||||
icon4.addFile(u":/Other/icons/convert.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.convertButton.setIcon(icon4)
|
||||
|
||||
self.gridLayout_4.addWidget(self.convertButton, 1, 3, 1, 1)
|
||||
|
||||
self.clearButton = QPushButton(self.buttonWidget)
|
||||
self.clearButton.setObjectName(u"clearButton")
|
||||
self.clearButton.setMinimumSize(QSize(0, 30))
|
||||
icon5 = QIcon()
|
||||
icon5.addFile(u":/Other/icons/clear.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.clearButton.setIcon(icon5)
|
||||
|
||||
self.gridLayout_4.addWidget(self.clearButton, 0, 3, 1, 1)
|
||||
|
||||
self.deviceBox = QComboBox(self.buttonWidget)
|
||||
self.deviceBox.setObjectName(u"deviceBox")
|
||||
self.deviceBox.setMinimumSize(QSize(0, 28))
|
||||
|
||||
self.gridLayout_4.addWidget(self.deviceBox, 1, 1, 1, 1)
|
||||
|
||||
self.fileButton = QPushButton(self.buttonWidget)
|
||||
self.fileButton.setObjectName(u"fileButton")
|
||||
self.fileButton.setMinimumSize(QSize(0, 30))
|
||||
icon6 = QIcon()
|
||||
icon6.addFile(u":/Other/icons/document_new.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.fileButton.setIcon(icon6)
|
||||
|
||||
self.gridLayout_4.addWidget(self.fileButton, 0, 1, 1, 1)
|
||||
|
||||
self.directoryButton = QPushButton(self.buttonWidget)
|
||||
self.directoryButton.setObjectName(u"directoryButton")
|
||||
sizePolicy3 = QSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum)
|
||||
sizePolicy3.setHorizontalStretch(0)
|
||||
sizePolicy3.setVerticalStretch(0)
|
||||
sizePolicy3.setHeightForWidth(self.directoryButton.sizePolicy().hasHeightForWidth())
|
||||
self.directoryButton.setSizePolicy(sizePolicy3)
|
||||
icon7 = QIcon()
|
||||
icon7.addFile(u":/Other/icons/folder_new.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.directoryButton.setIcon(icon7)
|
||||
|
||||
self.gridLayout_4.addWidget(self.directoryButton, 0, 4, 1, 1)
|
||||
|
||||
self.formatBox = QComboBox(self.buttonWidget)
|
||||
self.formatBox.setObjectName(u"formatBox")
|
||||
self.formatBox.setMinimumSize(QSize(0, 28))
|
||||
|
||||
self.gridLayout_4.addWidget(self.formatBox, 1, 4, 1, 1)
|
||||
|
||||
self.clearButton.raise_()
|
||||
self.deviceBox.raise_()
|
||||
self.convertButton.raise_()
|
||||
self.fileButton.raise_()
|
||||
self.directoryButton.raise_()
|
||||
self.formatBox.raise_()
|
||||
|
||||
self.gridLayout.addWidget(self.buttonWidget, 3, 0, 1, 2)
|
||||
|
||||
self.jobList = QListWidget(self.centralWidget)
|
||||
self.jobList.setObjectName(u"jobList")
|
||||
self.jobList.setMinimumSize(QSize(0, 150))
|
||||
self.jobList.setStyleSheet(u"")
|
||||
self.jobList.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection)
|
||||
self.jobList.setVerticalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel)
|
||||
self.jobList.setHorizontalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel)
|
||||
|
||||
self.gridLayout.addWidget(self.jobList, 2, 0, 1, 2)
|
||||
|
||||
self.chunkSizeWidget = QWidget(self.centralWidget)
|
||||
self.chunkSizeWidget.setObjectName(u"chunkSizeWidget")
|
||||
sizePolicy4 = QSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Fixed)
|
||||
sizePolicy4.setHorizontalStretch(0)
|
||||
sizePolicy4.setVerticalStretch(0)
|
||||
sizePolicy4.setHeightForWidth(self.chunkSizeWidget.sizePolicy().hasHeightForWidth())
|
||||
self.chunkSizeWidget.setSizePolicy(sizePolicy4)
|
||||
self.chunkSizeWidget.setVisible(False)
|
||||
self.horizontalLayout_4 = QHBoxLayout(self.chunkSizeWidget)
|
||||
self.horizontalLayout_4.setSpacing(0)
|
||||
self.horizontalLayout_4.setObjectName(u"horizontalLayout_4")
|
||||
self.horizontalLayout_4.setContentsMargins(0, 0, 0, 0)
|
||||
self.chunkSizeLabel = QLabel(self.chunkSizeWidget)
|
||||
self.chunkSizeLabel.setObjectName(u"chunkSizeLabel")
|
||||
sizePolicy5 = QSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Preferred)
|
||||
sizePolicy5.setHorizontalStretch(0)
|
||||
sizePolicy5.setVerticalStretch(0)
|
||||
sizePolicy5.setHeightForWidth(self.chunkSizeLabel.sizePolicy().hasHeightForWidth())
|
||||
self.chunkSizeLabel.setSizePolicy(sizePolicy5)
|
||||
|
||||
self.horizontalLayout_4.addWidget(self.chunkSizeLabel)
|
||||
|
||||
self.chunkSizeBox = QSpinBox(self.chunkSizeWidget)
|
||||
self.chunkSizeBox.setObjectName(u"chunkSizeBox")
|
||||
self.chunkSizeBox.setMinimum(100)
|
||||
self.chunkSizeBox.setMaximum(600)
|
||||
self.chunkSizeBox.setValue(400)
|
||||
|
||||
self.horizontalLayout_4.addWidget(self.chunkSizeBox)
|
||||
|
||||
self.chunkSizeWarnLabel = QLabel(self.chunkSizeWidget)
|
||||
self.chunkSizeWarnLabel.setObjectName(u"chunkSizeWarnLabel")
|
||||
sizePolicy5.setHeightForWidth(self.chunkSizeWarnLabel.sizePolicy().hasHeightForWidth())
|
||||
self.chunkSizeWarnLabel.setSizePolicy(sizePolicy5)
|
||||
|
||||
self.horizontalLayout_4.addWidget(self.chunkSizeWarnLabel)
|
||||
|
||||
|
||||
self.gridLayout.addWidget(self.chunkSizeWidget, 6, 0, 1, 1)
|
||||
|
||||
self.optionWidget = QWidget(self.centralWidget)
|
||||
self.optionWidget.setObjectName(u"optionWidget")
|
||||
self.gridLayout_2 = QGridLayout(self.optionWidget)
|
||||
@@ -42,11 +289,8 @@ class Ui_mainWindow(object):
|
||||
self.gridLayout_2.setContentsMargins(0, 0, 0, 0)
|
||||
self.titleEdit = QLineEdit(self.optionWidget)
|
||||
self.titleEdit.setObjectName(u"titleEdit")
|
||||
sizePolicy = QSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.titleEdit.sizePolicy().hasHeightForWidth())
|
||||
self.titleEdit.setSizePolicy(sizePolicy)
|
||||
sizePolicy4.setHeightForWidth(self.titleEdit.sizePolicy().hasHeightForWidth())
|
||||
self.titleEdit.setSizePolicy(sizePolicy4)
|
||||
self.titleEdit.setFocusPolicy(Qt.FocusPolicy.ClickFocus)
|
||||
self.titleEdit.setClearButtonEnabled(False)
|
||||
|
||||
@@ -148,8 +392,8 @@ class Ui_mainWindow(object):
|
||||
|
||||
self.authorEdit = QLineEdit(self.optionWidget)
|
||||
self.authorEdit.setObjectName(u"authorEdit")
|
||||
sizePolicy.setHeightForWidth(self.authorEdit.sizePolicy().hasHeightForWidth())
|
||||
self.authorEdit.setSizePolicy(sizePolicy)
|
||||
sizePolicy4.setHeightForWidth(self.authorEdit.sizePolicy().hasHeightForWidth())
|
||||
self.authorEdit.setSizePolicy(sizePolicy4)
|
||||
self.authorEdit.setFocusPolicy(Qt.FocusPolicy.ClickFocus)
|
||||
self.authorEdit.setClearButtonEnabled(False)
|
||||
|
||||
@@ -190,57 +434,36 @@ class Ui_mainWindow(object):
|
||||
|
||||
self.gridLayout_2.addWidget(self.autocontrastBox, 9, 2, 1, 1)
|
||||
|
||||
self.outputFolderWidget = QWidget(self.optionWidget)
|
||||
self.outputFolderWidget.setObjectName(u"outputFolderWidget")
|
||||
self.horizontalLayout_3 = QHBoxLayout(self.outputFolderWidget)
|
||||
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
|
||||
self.defaultOutputFolderBox = QCheckBox(self.outputFolderWidget)
|
||||
self.defaultOutputFolderBox.setObjectName(u"defaultOutputFolderBox")
|
||||
sizePolicy.setHeightForWidth(self.defaultOutputFolderBox.sizePolicy().hasHeightForWidth())
|
||||
self.defaultOutputFolderBox.setSizePolicy(sizePolicy)
|
||||
self.defaultOutputFolderBox.setTristate(True)
|
||||
|
||||
self.horizontalLayout_3.addWidget(self.defaultOutputFolderBox)
|
||||
|
||||
self.defaultOutputFolderButton = QPushButton(self.outputFolderWidget)
|
||||
self.defaultOutputFolderButton.setObjectName(u"defaultOutputFolderButton")
|
||||
self.defaultOutputFolderButton.setMinimumSize(QSize(0, 30))
|
||||
self.defaultOutputFolderButton.setIcon(icon7)
|
||||
|
||||
self.horizontalLayout_3.addWidget(self.defaultOutputFolderButton)
|
||||
|
||||
|
||||
self.gridLayout_2.addWidget(self.outputFolderWidget, 0, 2, 1, 1)
|
||||
|
||||
self.jpegQualityBox = QCheckBox(self.optionWidget)
|
||||
self.jpegQualityBox.setObjectName(u"jpegQualityBox")
|
||||
|
||||
self.gridLayout_2.addWidget(self.jpegQualityBox, 8, 0, 1, 1)
|
||||
|
||||
|
||||
self.gridLayout.addWidget(self.optionWidget, 5, 0, 1, 2)
|
||||
|
||||
self.jobList = QListWidget(self.centralWidget)
|
||||
self.jobList.setObjectName(u"jobList")
|
||||
self.jobList.setMinimumSize(QSize(0, 150))
|
||||
self.jobList.setStyleSheet(u"")
|
||||
self.jobList.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection)
|
||||
self.jobList.setVerticalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel)
|
||||
self.jobList.setHorizontalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel)
|
||||
|
||||
self.gridLayout.addWidget(self.jobList, 2, 0, 1, 2)
|
||||
|
||||
self.customWidget = QWidget(self.centralWidget)
|
||||
self.customWidget.setObjectName(u"customWidget")
|
||||
self.customWidget.setVisible(False)
|
||||
self.gridLayout_3 = QGridLayout(self.customWidget)
|
||||
self.gridLayout_3.setObjectName(u"gridLayout_3")
|
||||
self.gridLayout_3.setContentsMargins(0, 0, 0, 0)
|
||||
self.hLabel = QLabel(self.customWidget)
|
||||
self.hLabel.setObjectName(u"hLabel")
|
||||
sizePolicy1 = QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Preferred)
|
||||
sizePolicy1.setHorizontalStretch(0)
|
||||
sizePolicy1.setVerticalStretch(0)
|
||||
sizePolicy1.setHeightForWidth(self.hLabel.sizePolicy().hasHeightForWidth())
|
||||
self.hLabel.setSizePolicy(sizePolicy1)
|
||||
|
||||
self.gridLayout_3.addWidget(self.hLabel, 0, 2, 1, 1)
|
||||
|
||||
self.widthBox = QSpinBox(self.customWidget)
|
||||
self.widthBox.setObjectName(u"widthBox")
|
||||
self.widthBox.setMaximum(6000)
|
||||
|
||||
self.gridLayout_3.addWidget(self.widthBox, 0, 1, 1, 1)
|
||||
|
||||
self.wLabel = QLabel(self.customWidget)
|
||||
self.wLabel.setObjectName(u"wLabel")
|
||||
sizePolicy1.setHeightForWidth(self.wLabel.sizePolicy().hasHeightForWidth())
|
||||
self.wLabel.setSizePolicy(sizePolicy1)
|
||||
|
||||
self.gridLayout_3.addWidget(self.wLabel, 0, 0, 1, 1)
|
||||
|
||||
self.heightBox = QSpinBox(self.customWidget)
|
||||
self.heightBox.setObjectName(u"heightBox")
|
||||
self.heightBox.setMaximum(8000)
|
||||
|
||||
self.gridLayout_3.addWidget(self.heightBox, 0, 3, 1, 1)
|
||||
|
||||
|
||||
self.gridLayout.addWidget(self.customWidget, 8, 0, 1, 2)
|
||||
|
||||
self.gammaWidget = QWidget(self.centralWidget)
|
||||
self.gammaWidget.setObjectName(u"gammaWidget")
|
||||
self.gammaWidget.setVisible(False)
|
||||
@@ -263,206 +486,29 @@ class Ui_mainWindow(object):
|
||||
|
||||
self.gridLayout.addWidget(self.gammaWidget, 7, 0, 1, 2)
|
||||
|
||||
self.toolWidget = QWidget(self.centralWidget)
|
||||
self.toolWidget.setObjectName(u"toolWidget")
|
||||
self.horizontalLayout = QHBoxLayout(self.toolWidget)
|
||||
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
||||
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.editorButton = QPushButton(self.toolWidget)
|
||||
self.editorButton.setObjectName(u"editorButton")
|
||||
self.editorButton.setMinimumSize(QSize(0, 30))
|
||||
icon1 = QIcon()
|
||||
icon1.addFile(u":/Other/icons/editor.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.editorButton.setIcon(icon1)
|
||||
self.jpegQualityWidget = QWidget(self.centralWidget)
|
||||
self.jpegQualityWidget.setObjectName(u"jpegQualityWidget")
|
||||
sizePolicy1.setHeightForWidth(self.jpegQualityWidget.sizePolicy().hasHeightForWidth())
|
||||
self.jpegQualityWidget.setSizePolicy(sizePolicy1)
|
||||
self.jpegQualityWidget.setVisible(False)
|
||||
self.horizontalLayout_12 = QHBoxLayout(self.jpegQualityWidget)
|
||||
self.horizontalLayout_12.setObjectName(u"horizontalLayout_12")
|
||||
self.horizontalLayout_12.setContentsMargins(0, 0, 0, 0)
|
||||
self.jpegQualityLabel = QLabel(self.jpegQualityWidget)
|
||||
self.jpegQualityLabel.setObjectName(u"jpegQualityLabel")
|
||||
|
||||
self.horizontalLayout.addWidget(self.editorButton)
|
||||
self.horizontalLayout_12.addWidget(self.jpegQualityLabel)
|
||||
|
||||
self.kofiButton = QPushButton(self.toolWidget)
|
||||
self.kofiButton.setObjectName(u"kofiButton")
|
||||
self.kofiButton.setMinimumSize(QSize(0, 30))
|
||||
icon2 = QIcon()
|
||||
icon2.addFile(u":/Brand/icons/kofi_symbol.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.kofiButton.setIcon(icon2)
|
||||
self.kofiButton.setIconSize(QSize(19, 16))
|
||||
self.jpegQualitySpinBox = QSpinBox(self.jpegQualityWidget)
|
||||
self.jpegQualitySpinBox.setObjectName(u"jpegQualitySpinBox")
|
||||
self.jpegQualitySpinBox.setMaximum(95)
|
||||
self.jpegQualitySpinBox.setSingleStep(5)
|
||||
self.jpegQualitySpinBox.setValue(85)
|
||||
|
||||
self.horizontalLayout.addWidget(self.kofiButton)
|
||||
|
||||
self.wikiButton = QPushButton(self.toolWidget)
|
||||
self.wikiButton.setObjectName(u"wikiButton")
|
||||
self.wikiButton.setMinimumSize(QSize(0, 30))
|
||||
icon3 = QIcon()
|
||||
icon3.addFile(u":/Other/icons/wiki.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.wikiButton.setIcon(icon3)
|
||||
|
||||
self.horizontalLayout.addWidget(self.wikiButton)
|
||||
self.horizontalLayout_12.addWidget(self.jpegQualitySpinBox)
|
||||
|
||||
|
||||
self.gridLayout.addWidget(self.toolWidget, 0, 0, 1, 2)
|
||||
|
||||
self.progressBar = QProgressBar(self.centralWidget)
|
||||
self.progressBar.setObjectName(u"progressBar")
|
||||
self.progressBar.setMinimumSize(QSize(0, 30))
|
||||
font = QFont()
|
||||
font.setBold(True)
|
||||
self.progressBar.setFont(font)
|
||||
self.progressBar.setVisible(False)
|
||||
self.progressBar.setAlignment(Qt.AlignmentFlag.AlignJustify|Qt.AlignmentFlag.AlignVCenter)
|
||||
|
||||
self.gridLayout.addWidget(self.progressBar, 1, 0, 1, 2)
|
||||
|
||||
self.croppingWidget = QWidget(self.centralWidget)
|
||||
self.croppingWidget.setObjectName(u"croppingWidget")
|
||||
self.croppingWidget.setVisible(False)
|
||||
self.gridLayout_5 = QGridLayout(self.croppingWidget)
|
||||
self.gridLayout_5.setObjectName(u"gridLayout_5")
|
||||
self.gridLayout_5.setContentsMargins(0, 0, 0, 0)
|
||||
self.preserveMarginLabel = QLabel(self.croppingWidget)
|
||||
self.preserveMarginLabel.setObjectName(u"preserveMarginLabel")
|
||||
|
||||
self.gridLayout_5.addWidget(self.preserveMarginLabel, 1, 0, 1, 1)
|
||||
|
||||
self.croppingPowerLabel = QLabel(self.croppingWidget)
|
||||
self.croppingPowerLabel.setObjectName(u"croppingPowerLabel")
|
||||
|
||||
self.gridLayout_5.addWidget(self.croppingPowerLabel, 0, 0, 1, 1)
|
||||
|
||||
self.croppingPowerSlider = QSlider(self.croppingWidget)
|
||||
self.croppingPowerSlider.setObjectName(u"croppingPowerSlider")
|
||||
self.croppingPowerSlider.setMaximum(300)
|
||||
self.croppingPowerSlider.setSingleStep(1)
|
||||
self.croppingPowerSlider.setOrientation(Qt.Orientation.Horizontal)
|
||||
|
||||
self.gridLayout_5.addWidget(self.croppingPowerSlider, 0, 1, 1, 1)
|
||||
|
||||
self.preserveMarginBox = QSpinBox(self.croppingWidget)
|
||||
self.preserveMarginBox.setObjectName(u"preserveMarginBox")
|
||||
sizePolicy2 = QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
|
||||
sizePolicy2.setHorizontalStretch(0)
|
||||
sizePolicy2.setVerticalStretch(0)
|
||||
sizePolicy2.setHeightForWidth(self.preserveMarginBox.sizePolicy().hasHeightForWidth())
|
||||
self.preserveMarginBox.setSizePolicy(sizePolicy2)
|
||||
self.preserveMarginBox.setMaximum(99)
|
||||
self.preserveMarginBox.setSingleStep(5)
|
||||
self.preserveMarginBox.setValue(0)
|
||||
|
||||
self.gridLayout_5.addWidget(self.preserveMarginBox, 1, 1, 1, 1)
|
||||
|
||||
|
||||
self.gridLayout.addWidget(self.croppingWidget, 9, 0, 1, 2)
|
||||
|
||||
self.buttonWidget = QWidget(self.centralWidget)
|
||||
self.buttonWidget.setObjectName(u"buttonWidget")
|
||||
sizePolicy3 = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
|
||||
sizePolicy3.setHorizontalStretch(0)
|
||||
sizePolicy3.setVerticalStretch(0)
|
||||
sizePolicy3.setHeightForWidth(self.buttonWidget.sizePolicy().hasHeightForWidth())
|
||||
self.buttonWidget.setSizePolicy(sizePolicy3)
|
||||
self.gridLayout_4 = QGridLayout(self.buttonWidget)
|
||||
self.gridLayout_4.setObjectName(u"gridLayout_4")
|
||||
self.gridLayout_4.setContentsMargins(0, 0, 0, 0)
|
||||
self.convertButton = QPushButton(self.buttonWidget)
|
||||
self.convertButton.setObjectName(u"convertButton")
|
||||
self.convertButton.setMinimumSize(QSize(0, 30))
|
||||
self.convertButton.setFont(font)
|
||||
icon4 = QIcon()
|
||||
icon4.addFile(u":/Other/icons/convert.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.convertButton.setIcon(icon4)
|
||||
|
||||
self.gridLayout_4.addWidget(self.convertButton, 1, 3, 1, 1)
|
||||
|
||||
self.clearButton = QPushButton(self.buttonWidget)
|
||||
self.clearButton.setObjectName(u"clearButton")
|
||||
self.clearButton.setMinimumSize(QSize(0, 30))
|
||||
icon5 = QIcon()
|
||||
icon5.addFile(u":/Other/icons/clear.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.clearButton.setIcon(icon5)
|
||||
|
||||
self.gridLayout_4.addWidget(self.clearButton, 0, 3, 1, 1)
|
||||
|
||||
self.deviceBox = QComboBox(self.buttonWidget)
|
||||
self.deviceBox.setObjectName(u"deviceBox")
|
||||
self.deviceBox.setMinimumSize(QSize(0, 28))
|
||||
|
||||
self.gridLayout_4.addWidget(self.deviceBox, 1, 1, 1, 1)
|
||||
|
||||
self.fileButton = QPushButton(self.buttonWidget)
|
||||
self.fileButton.setObjectName(u"fileButton")
|
||||
self.fileButton.setMinimumSize(QSize(0, 30))
|
||||
icon6 = QIcon()
|
||||
icon6.addFile(u":/Other/icons/document_new.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.fileButton.setIcon(icon6)
|
||||
|
||||
self.gridLayout_4.addWidget(self.fileButton, 0, 1, 1, 1)
|
||||
|
||||
self.defaultOutputFolderButton = QPushButton(self.buttonWidget)
|
||||
self.defaultOutputFolderButton.setObjectName(u"defaultOutputFolderButton")
|
||||
self.defaultOutputFolderButton.setMinimumSize(QSize(0, 30))
|
||||
icon7 = QIcon()
|
||||
icon7.addFile(u":/Other/icons/folder_new.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
|
||||
self.defaultOutputFolderButton.setIcon(icon7)
|
||||
|
||||
self.gridLayout_4.addWidget(self.defaultOutputFolderButton, 0, 5, 1, 1)
|
||||
|
||||
self.defaultOutputFolderBox = QCheckBox(self.buttonWidget)
|
||||
self.defaultOutputFolderBox.setObjectName(u"defaultOutputFolderBox")
|
||||
sizePolicy2.setHeightForWidth(self.defaultOutputFolderBox.sizePolicy().hasHeightForWidth())
|
||||
self.defaultOutputFolderBox.setSizePolicy(sizePolicy2)
|
||||
self.defaultOutputFolderBox.setTristate(True)
|
||||
|
||||
self.gridLayout_4.addWidget(self.defaultOutputFolderBox, 0, 4, 1, 1)
|
||||
|
||||
self.formatBox = QComboBox(self.buttonWidget)
|
||||
self.formatBox.setObjectName(u"formatBox")
|
||||
self.formatBox.setMinimumSize(QSize(0, 28))
|
||||
|
||||
self.gridLayout_4.addWidget(self.formatBox, 1, 4, 1, 2)
|
||||
|
||||
self.clearButton.raise_()
|
||||
self.deviceBox.raise_()
|
||||
self.convertButton.raise_()
|
||||
self.formatBox.raise_()
|
||||
self.defaultOutputFolderButton.raise_()
|
||||
self.fileButton.raise_()
|
||||
self.defaultOutputFolderBox.raise_()
|
||||
|
||||
self.gridLayout.addWidget(self.buttonWidget, 3, 0, 1, 2)
|
||||
|
||||
self.chunkSizeWidget = QWidget(self.centralWidget)
|
||||
self.chunkSizeWidget.setObjectName(u"chunkSizeWidget")
|
||||
sizePolicy.setHeightForWidth(self.chunkSizeWidget.sizePolicy().hasHeightForWidth())
|
||||
self.chunkSizeWidget.setSizePolicy(sizePolicy)
|
||||
self.chunkSizeWidget.setVisible(False)
|
||||
self.horizontalLayout_4 = QHBoxLayout(self.chunkSizeWidget)
|
||||
self.horizontalLayout_4.setSpacing(0)
|
||||
self.horizontalLayout_4.setObjectName(u"horizontalLayout_4")
|
||||
self.horizontalLayout_4.setContentsMargins(0, 0, 0, 0)
|
||||
self.chunkSizeLabel = QLabel(self.chunkSizeWidget)
|
||||
self.chunkSizeLabel.setObjectName(u"chunkSizeLabel")
|
||||
sizePolicy4 = QSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Preferred)
|
||||
sizePolicy4.setHorizontalStretch(0)
|
||||
sizePolicy4.setVerticalStretch(0)
|
||||
sizePolicy4.setHeightForWidth(self.chunkSizeLabel.sizePolicy().hasHeightForWidth())
|
||||
self.chunkSizeLabel.setSizePolicy(sizePolicy4)
|
||||
|
||||
self.horizontalLayout_4.addWidget(self.chunkSizeLabel)
|
||||
|
||||
self.chunkSizeBox = QSpinBox(self.chunkSizeWidget)
|
||||
self.chunkSizeBox.setObjectName(u"chunkSizeBox")
|
||||
self.chunkSizeBox.setMinimum(100)
|
||||
self.chunkSizeBox.setMaximum(600)
|
||||
self.chunkSizeBox.setValue(400)
|
||||
|
||||
self.horizontalLayout_4.addWidget(self.chunkSizeBox)
|
||||
|
||||
self.chunkSizeWarnLabel = QLabel(self.chunkSizeWidget)
|
||||
self.chunkSizeWarnLabel.setObjectName(u"chunkSizeWarnLabel")
|
||||
sizePolicy4.setHeightForWidth(self.chunkSizeWarnLabel.sizePolicy().hasHeightForWidth())
|
||||
self.chunkSizeWarnLabel.setSizePolicy(sizePolicy4)
|
||||
|
||||
self.horizontalLayout_4.addWidget(self.chunkSizeWarnLabel)
|
||||
|
||||
|
||||
self.gridLayout.addWidget(self.chunkSizeWidget, 6, 0, 1, 1)
|
||||
self.gridLayout.addWidget(self.jpegQualityWidget, 10, 0, 1, 1)
|
||||
|
||||
mainWindow.setCentralWidget(self.centralWidget)
|
||||
self.statusBar = QStatusBar(mainWindow)
|
||||
@@ -471,13 +517,10 @@ class Ui_mainWindow(object):
|
||||
mainWindow.setStatusBar(self.statusBar)
|
||||
QWidget.setTabOrder(self.jobList, self.fileButton)
|
||||
QWidget.setTabOrder(self.fileButton, self.clearButton)
|
||||
QWidget.setTabOrder(self.clearButton, self.defaultOutputFolderButton)
|
||||
QWidget.setTabOrder(self.defaultOutputFolderButton, self.defaultOutputFolderBox)
|
||||
QWidget.setTabOrder(self.defaultOutputFolderBox, self.deviceBox)
|
||||
QWidget.setTabOrder(self.clearButton, self.deviceBox)
|
||||
QWidget.setTabOrder(self.deviceBox, self.widthBox)
|
||||
QWidget.setTabOrder(self.widthBox, self.heightBox)
|
||||
QWidget.setTabOrder(self.heightBox, self.formatBox)
|
||||
QWidget.setTabOrder(self.formatBox, self.convertButton)
|
||||
QWidget.setTabOrder(self.heightBox, self.convertButton)
|
||||
QWidget.setTabOrder(self.convertButton, self.mangaBox)
|
||||
QWidget.setTabOrder(self.mangaBox, self.rotateBox)
|
||||
QWidget.setTabOrder(self.rotateBox, self.qualityBox)
|
||||
@@ -517,6 +560,58 @@ class Ui_mainWindow(object):
|
||||
|
||||
def retranslateUi(self, mainWindow):
|
||||
mainWindow.setWindowTitle(QCoreApplication.translate("mainWindow", u"Kindle Comic Converter", None))
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.editorButton.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p style='white-space:pre'>Shift+Click to edit directory.</p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
self.editorButton.setText(QCoreApplication.translate("mainWindow", u"Metadata Editor", None))
|
||||
self.kofiButton.setText(QCoreApplication.translate("mainWindow", u"Support me on Ko-fi", None))
|
||||
self.wikiButton.setText(QCoreApplication.translate("mainWindow", u"Wiki", None))
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.preserveMarginLabel.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p>After calculating the cropping boundaries, "back up" a specified percentage amount.</p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
self.preserveMarginLabel.setText(QCoreApplication.translate("mainWindow", u"Preserve Margin %", None))
|
||||
self.croppingPowerLabel.setText(QCoreApplication.translate("mainWindow", u"Cropping power:", None))
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.hLabel.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p style='white-space:pre'>Resolution of the target device.</p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
self.hLabel.setText(QCoreApplication.translate("mainWindow", u"Custom height:", None))
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.widthBox.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p style='white-space:pre'>Resolution of the target device.</p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.wLabel.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p style='white-space:pre'>Resolution of the target device.</p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
self.wLabel.setText(QCoreApplication.translate("mainWindow", u"Custom width:", None))
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.heightBox.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p style='white-space:pre'>Resolution of the target device.</p></body></html>", None))
|
||||
#endif // 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))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
self.convertButton.setText(QCoreApplication.translate("mainWindow", u"Convert", None))
|
||||
self.clearButton.setText(QCoreApplication.translate("mainWindow", u"Clear list", None))
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.deviceBox.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p style='white-space:pre'>Target device.</p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.fileButton.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p style='white-space:pre'>Add CBR, CBZ, CB7 or PDF file to queue.</p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
self.fileButton.setText(QCoreApplication.translate("mainWindow", u"Add input file(s)", None))
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.directoryButton.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p style='white-space:pre'>Add directory containing JPG, PNG or GIF files to queue.<br/><span style=\" font-weight:600;\">CBR, CBZ and CB7 files inside will not be processed!</span></p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
self.directoryButton.setText(QCoreApplication.translate("mainWindow", u"Add input folder(s)", None))
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.formatBox.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p style='white-space:pre'>Output format.</p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.jobList.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p>Double click on source to open it in metadata editor.</p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.chunkSizeWidget.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p>Warning: chunk size greater than default may cause<br/>performance/battery issues, especially on older devices.</p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
self.chunkSizeLabel.setText(QCoreApplication.translate("mainWindow", u"Chunk size MB:", None))
|
||||
self.chunkSizeWarnLabel.setText(QCoreApplication.translate("mainWindow", u"Greater than default may cause performance issues on older ereaders.", None))
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.titleEdit.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p>Default Title</p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
@@ -622,61 +717,22 @@ class Ui_mainWindow(object):
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
self.autocontrastBox.setText(QCoreApplication.translate("mainWindow", u"Autocontrast", None))
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.jobList.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p>Double click on source to open it in metadata editor.</p></body></html>", None))
|
||||
self.defaultOutputFolderBox.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - next to source<br/></span>Place output files next to source files</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - folder next to source<br/></span>Place output files in a folder next to source files</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Custom<br/></span>Place output files in custom directory specified by right button</p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.hLabel.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p style='white-space:pre'>Resolution of the target device.</p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
self.hLabel.setText(QCoreApplication.translate("mainWindow", u"Custom height:", None))
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.widthBox.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p style='white-space:pre'>Resolution of the target device.</p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.wLabel.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p style='white-space:pre'>Resolution of the target device.</p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
self.wLabel.setText(QCoreApplication.translate("mainWindow", u"Custom width:", None))
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.heightBox.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p style='white-space:pre'>Resolution of the target device.</p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
self.gammaLabel.setText(QCoreApplication.translate("mainWindow", u"Gamma: Auto", None))
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.editorButton.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p style='white-space:pre'>Shift+Click to edit directory.</p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
self.editorButton.setText(QCoreApplication.translate("mainWindow", u"Metadata Editor", None))
|
||||
self.kofiButton.setText(QCoreApplication.translate("mainWindow", u"Support me on Ko-fi", None))
|
||||
self.wikiButton.setText(QCoreApplication.translate("mainWindow", u"Wiki", None))
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.preserveMarginLabel.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p>After calculating the cropping boundaries, "back up" a specified percentage amount.</p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
self.preserveMarginLabel.setText(QCoreApplication.translate("mainWindow", u"Preserve Margin %", None))
|
||||
self.croppingPowerLabel.setText(QCoreApplication.translate("mainWindow", u"Cropping power:", None))
|
||||
#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))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
self.convertButton.setText(QCoreApplication.translate("mainWindow", u"Convert", None))
|
||||
self.clearButton.setText(QCoreApplication.translate("mainWindow", u"Clear list", None))
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.deviceBox.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p style='white-space:pre'>Target device.</p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.fileButton.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p style='white-space:pre'>Add CBR, CBZ, CB7 or PDF file to queue.</p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
self.fileButton.setText(QCoreApplication.translate("mainWindow", u"Add file(s)", None))
|
||||
self.defaultOutputFolderBox.setText(QCoreApplication.translate("mainWindow", u"Output Folder", None))
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.defaultOutputFolderButton.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p>Use this to select the default output directory.</p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
self.defaultOutputFolderButton.setText("")
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.defaultOutputFolderBox.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - next to source<br/></span>Place output files next to source files</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - folder next to source<br/></span>Place output files in a folder next to source files</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Custom<br/></span>Place output files in custom directory specified by right button</p></body></html>", None))
|
||||
self.jpegQualityBox.setToolTip(QCoreApplication.translate("mainWindow", u"The JPEG quality, on a scale from 0 (worst) to 95 (best). \n"
|
||||
"\n"
|
||||
"Default is 85 for most devices besides Kindle Scribe and Colorsoft, which are 90.\n"
|
||||
"\n"
|
||||
"Higher values are larger and higher quality, and may resolve blank page issues.", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
self.defaultOutputFolderBox.setText(QCoreApplication.translate("mainWindow", u"Output Folder", None))
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.formatBox.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p style='white-space:pre'>Output format.</p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
#if QT_CONFIG(tooltip)
|
||||
self.chunkSizeWidget.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p>Warning: chunk size greater than default may cause<br/>performance/battery issues, especially on older devices.</p></body></html>", None))
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
self.chunkSizeLabel.setText(QCoreApplication.translate("mainWindow", u"Chunk size MB:", None))
|
||||
self.chunkSizeWarnLabel.setText(QCoreApplication.translate("mainWindow", u"Greater than default may cause performance issues on older ereaders.", None))
|
||||
self.jpegQualityBox.setText(QCoreApplication.translate("mainWindow", u"Custom JPEG Quality", None))
|
||||
self.gammaLabel.setText(QCoreApplication.translate("mainWindow", u"Gamma: Auto", None))
|
||||
self.jpegQualityLabel.setText(QCoreApplication.translate("mainWindow", u"JPEG Quality:", None))
|
||||
# retranslateUi
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
__version__ = '9.3.6'
|
||||
__version__ = '9.4.0'
|
||||
__license__ = 'ISC'
|
||||
__copyright__ = '2012-2022, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>, darodi'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
@@ -851,14 +851,16 @@ def mupdf_pdf_process_pages_parallel(filename, output_dir, target_height):
|
||||
|
||||
|
||||
|
||||
def getWorkFolder(afile):
|
||||
def getWorkFolder(afile, workdir=None):
|
||||
if not workdir:
|
||||
workdir = mkdtemp('', 'KCC-')
|
||||
fullPath = os.path.join(workdir, 'OEBPS', 'Images')
|
||||
else:
|
||||
fullPath = workdir
|
||||
if os.path.isdir(afile):
|
||||
if disk_usage(gettempdir())[2] < getDirectorySize(afile) * 2.5:
|
||||
raise UserWarning("Not enough disk space to perform conversion.")
|
||||
workdir = mkdtemp('', 'KCC-', os.path.dirname(afile))
|
||||
try:
|
||||
os.rmdir(workdir)
|
||||
fullPath = os.path.join(workdir, 'OEBPS', 'Images')
|
||||
copytree(afile, fullPath)
|
||||
sanitizePermissions(fullPath)
|
||||
return workdir
|
||||
@@ -869,8 +871,6 @@ def getWorkFolder(afile):
|
||||
if disk_usage(gettempdir())[2] < os.path.getsize(afile) * 2.5:
|
||||
raise UserWarning("Not enough disk space to perform conversion.")
|
||||
if afile.lower().endswith('.pdf'):
|
||||
workdir = mkdtemp('', 'KCC-', os.path.dirname(afile))
|
||||
fullPath = os.path.join(workdir, 'OEBPS', 'Images')
|
||||
if not os.path.exists(fullPath):
|
||||
os.makedirs(fullPath)
|
||||
path = workdir
|
||||
@@ -887,8 +887,6 @@ def getWorkFolder(afile):
|
||||
raise UserWarning(f"Failed to extract images from PDF file. {e}")
|
||||
return workdir
|
||||
else:
|
||||
workdir = mkdtemp('', 'KCC-', os.path.dirname(afile))
|
||||
fullPath = os.path.join(workdir, 'OEBPS', 'Images')
|
||||
if not os.path.exists(fullPath):
|
||||
os.makedirs(fullPath)
|
||||
try:
|
||||
@@ -1239,7 +1237,7 @@ def detectSuboptimalProcessing(tmppath, orgpath):
|
||||
GUI.addMessage.emit('Source files are probably created by KCC. The second conversion will decrease quality.'
|
||||
, 'warning', False)
|
||||
GUI.addMessage.emit('', '', False)
|
||||
if imageSmaller > imageNumber * 0.25 and not options.upscale and not options.stretch and options.profile != 'KS':
|
||||
if imageSmaller > imageNumber * 0.25 and not options.upscale and not options.stretch and not options.profile.startswith('KS'):
|
||||
print("WARNING: More than 25% of images are smaller than target device resolution. "
|
||||
"Consider enabling stretching or upscaling to improve readability.")
|
||||
if GUI:
|
||||
@@ -1382,6 +1380,8 @@ def makeParser():
|
||||
help="Create PNG files instead JPEG")
|
||||
processing_options.add_argument("--mozjpeg", action="store_true", dest="mozjpeg", default=False,
|
||||
help="Create JPEG files using mozJpeg")
|
||||
processing_options.add_argument("--jpeg-quality", type=int, dest="jpegquality",
|
||||
help="The JPEG quality, on a scale from 0 (worst) to 95 (best). Default 85 for most devices.")
|
||||
processing_options.add_argument("--maximizestrips", action="store_true", dest="maximizestrips", default=False,
|
||||
help="Turn 1x4 strips to 2x2 strips")
|
||||
processing_options.add_argument("-d", "--delete", action="store_true", dest="delete", default=False,
|
||||
@@ -1481,6 +1481,11 @@ def checkOptions(options):
|
||||
image.ProfileData.Profiles["Custom"] = newProfile
|
||||
options.profile = "Custom"
|
||||
options.profileData = image.ProfileData.Profiles[options.profile]
|
||||
if not options.jpegquality:
|
||||
if options.profile.startswith('KS') or options.profile == 'KCS':
|
||||
options.jpegquality = 90
|
||||
else:
|
||||
options.jpegquality = 85
|
||||
return options
|
||||
|
||||
|
||||
@@ -1532,17 +1537,15 @@ def makeFusion(sources: List[str]):
|
||||
print(f"Processing {source}...")
|
||||
checkPre(source)
|
||||
print("Checking images...")
|
||||
path = getWorkFolder(source)
|
||||
pathfinder = os.path.join(path, "OEBPS", "Images")
|
||||
sanitizeTree(pathfinder)
|
||||
# TODO: remove flattenTree when subchapters are supported
|
||||
flattenTree(pathfinder)
|
||||
source_path = Path(source)
|
||||
if source_path.is_file():
|
||||
os.renames(pathfinder, fusion_path.joinpath(source_path.stem))
|
||||
targetpath = fusion_path.joinpath(source_path.stem)
|
||||
else:
|
||||
os.renames(pathfinder, fusion_path.joinpath(source_path.name))
|
||||
|
||||
targetpath = fusion_path.joinpath(source_path.name)
|
||||
getWorkFolder(source, str(targetpath))
|
||||
sanitizeTree(targetpath)
|
||||
# TODO: remove flattenTree when subchapters are supported
|
||||
flattenTree(targetpath)
|
||||
|
||||
end = perf_counter()
|
||||
print(f"makefusion: {end - start} seconds")
|
||||
@@ -1560,7 +1563,7 @@ def makeBook(source, qtgui=None, job_progress=''):
|
||||
else:
|
||||
checkTools(source)
|
||||
options.kindle_azw3 = options.iskindle and ('MOBI' in options.format or 'EPUB' in options.format)
|
||||
options.kindle_scribe_azw3 = options.profile == 'KS' and ('MOBI' in options.format or 'EPUB' in options.format)
|
||||
options.kindle_scribe_azw3 = options.profile.startswith('KS') and options.kindle_azw3
|
||||
checkPre(source)
|
||||
print(f"{job_progress}Preparing source images...")
|
||||
path = getWorkFolder(source)
|
||||
|
||||
@@ -67,13 +67,14 @@ def mergeDirectory(work):
|
||||
result = Image.new('RGB', (targetWidth, targetHeight))
|
||||
y = 0
|
||||
for i in imagesValid:
|
||||
img = Image.open(i).convert('RGB')
|
||||
if img.size[0] < targetWidth or img.size[0] > targetWidth:
|
||||
widthPercent = (targetWidth / float(img.size[0]))
|
||||
heightSize = int((float(img.size[1]) * float(widthPercent)))
|
||||
img = ImageOps.fit(img, (targetWidth, heightSize), method=Image.BICUBIC, centering=(0.5, 0.5))
|
||||
result.paste(img, (0, y))
|
||||
y += img.size[1]
|
||||
with Image.open(i) as img:
|
||||
img = img.convert('RGB')
|
||||
if img.size[0] < targetWidth or img.size[0] > targetWidth:
|
||||
widthPercent = (targetWidth / float(img.size[0]))
|
||||
heightSize = int((float(img.size[1]) * float(widthPercent)))
|
||||
img = ImageOps.fit(img, (targetWidth, heightSize), method=Image.BICUBIC, centering=(0.5, 0.5))
|
||||
result.paste(img, (0, y))
|
||||
y += img.size[1]
|
||||
os.remove(i)
|
||||
savePath = os.path.split(imagesValid[0])
|
||||
result.save(os.path.join(savePath[0], os.path.splitext(savePath[1])[0] + '.png'), 'PNG')
|
||||
@@ -253,10 +254,8 @@ def main(argv=None, job_progress='', qtgui=None):
|
||||
return 1
|
||||
if args.height > 0:
|
||||
for sourceDir in args.input:
|
||||
targetDir = sourceDir + "-Splitted"
|
||||
targetDir = sourceDir
|
||||
if os.path.isdir(sourceDir):
|
||||
rmtree(targetDir, True)
|
||||
os.renames(sourceDir, targetDir)
|
||||
work = []
|
||||
pagenumber = 1
|
||||
splitWorkerOutput = []
|
||||
@@ -313,8 +312,6 @@ def main(argv=None, job_progress='', qtgui=None):
|
||||
rmtree(targetDir, True)
|
||||
raise RuntimeError("One of workers crashed. Cause: " + splitWorkerOutput[0][0],
|
||||
splitWorkerOutput[0][1])
|
||||
if args.inPlace:
|
||||
os.renames(targetDir, sourceDir)
|
||||
else:
|
||||
rmtree(targetDir, True)
|
||||
raise UserWarning("C2P: Source directory is empty.")
|
||||
|
||||
@@ -101,8 +101,10 @@ class ProfileData:
|
||||
'KO': ("Kindle Oasis 2/3/Paperwhite 12", (1264, 1680), Palette16, 1.0),
|
||||
'K11': ("Kindle 11", (1072, 1448), Palette16, 1.0),
|
||||
'KPW5': ("Kindle Paperwhite 5/Signature Edition", (1236, 1648), Palette16, 1.0),
|
||||
'KS': ("Kindle Scribe", (1860, 2480), Palette16, 1.0),
|
||||
'KS': ("Kindle Scribe 1/2", (1860, 2480), Palette16, 1.0),
|
||||
'KCS': ("Kindle Colorsoft", (1264, 1680), Palette16, 1.0),
|
||||
'KS3': ("Kindle Scribe 3", (1920, 2640), Palette16, 1.0),
|
||||
'KSCS': ("Kindle Scribe Colorsoft", (1920, 2640), Palette16, 1.0),
|
||||
}
|
||||
|
||||
ProfilesKindle = {
|
||||
@@ -406,13 +408,13 @@ class ComicPage:
|
||||
targetPath += '.jpg'
|
||||
if self.opt.mozjpeg:
|
||||
with io.BytesIO() as output:
|
||||
image.save(output, format="JPEG", optimize=1, quality=85)
|
||||
image.save(output, format="JPEG", optimize=1, quality=self.opt.jpegquality)
|
||||
input_jpeg_bytes = output.getvalue()
|
||||
output_jpeg_bytes = mozjpeg_lossless_optimization.optimize(input_jpeg_bytes)
|
||||
with open(targetPath, "wb") as output_jpeg_file:
|
||||
output_jpeg_file.write(output_jpeg_bytes)
|
||||
else:
|
||||
image.save(targetPath, 'JPEG', optimize=1, quality=85)
|
||||
image.save(targetPath, 'JPEG', optimize=1, quality=self.opt.jpegquality)
|
||||
return targetPath
|
||||
|
||||
def gammaCorrectImage(self):
|
||||
@@ -485,7 +487,7 @@ class ComicPage:
|
||||
if self.opt.kindle_azw3 and any(dim > 1920 for dim in self.image.size):
|
||||
self.image = ImageOps.contain(self.image, (1920, 1920), Image.Resampling.LANCZOS)
|
||||
elif self.image.size[0] > self.size[0] * 2 or self.image.size[1] > self.size[1]:
|
||||
self.image = ImageOps.contain(self.image, (self.size[0] * 2, self.size[1], Image.Resampling.LANCZOS))
|
||||
self.image = ImageOps.contain(self.image, (self.size[0] * 2, self.size[1]), Image.Resampling.LANCZOS)
|
||||
return
|
||||
|
||||
ratio_device = float(self.size[1]) / float(self.size[0])
|
||||
@@ -562,6 +564,7 @@ class Cover:
|
||||
|
||||
size = list(self.options.profileData[1])
|
||||
if self.options.kindle_scribe_azw3:
|
||||
size[0] = min(size[0], 1920)
|
||||
size[1] = min(size[1], 1920)
|
||||
self.image.thumbnail(tuple(size), Image.Resampling.LANCZOS)
|
||||
|
||||
@@ -581,7 +584,7 @@ class Cover:
|
||||
def save_to_epub(self, target, tomeid, len_tomes=0):
|
||||
try:
|
||||
if tomeid == 0:
|
||||
self.image.save(target, "JPEG", optimize=1, quality=85)
|
||||
self.image.save(target, "JPEG", optimize=1, quality=self.options.jpegquality)
|
||||
else:
|
||||
copy = self.image.copy()
|
||||
draw = ImageDraw.Draw(copy)
|
||||
@@ -595,7 +598,7 @@ class Cover:
|
||||
stroke_fill=0,
|
||||
stroke_width=25
|
||||
)
|
||||
copy.save(target, "JPEG", optimize=1, quality=85)
|
||||
copy.save(target, "JPEG", optimize=1, quality=self.options.jpegquality)
|
||||
except IOError:
|
||||
raise RuntimeError('Failed to save cover.')
|
||||
|
||||
@@ -603,6 +606,6 @@ class Cover:
|
||||
self.image = ImageOps.contain(self.image, (300, 470), Image.Resampling.LANCZOS)
|
||||
try:
|
||||
self.image.save(os.path.join(kindle.path.split('documents')[0], 'system', 'thumbnails',
|
||||
'thumbnail_' + asin + '_EBOK_portrait.jpg'), 'JPEG', optimize=1, quality=85)
|
||||
'thumbnail_' + asin + '_EBOK_portrait.jpg'), 'JPEG', optimize=1, quality=self.options.jpegquality)
|
||||
except IOError:
|
||||
raise RuntimeError('Failed to upload cover.')
|
||||
|
||||
4
setup.py
4
setup.py
@@ -40,8 +40,8 @@ class BuildBinaryCommand(setuptools.Command):
|
||||
if sys.platform == 'darwin':
|
||||
os.system('pyinstaller --hidden-import=_cffi_backend -y -D -i icons/comic2ebook.icns -n "Kindle Comic Converter" -w -s kcc.py')
|
||||
# TODO /usr/bin/codesign --force -s "$MACOS_CERTIFICATE_NAME" --options runtime dist/Applications/Kindle\ Comic\ Converter.app -v
|
||||
min_os = os.getenv('MACOSX_DEPLOYMENT_TARGET')
|
||||
if min_os:
|
||||
min_os = os.getenv('MACOSX_DEPLOYMENT_TARGET', '')
|
||||
if min_os.startswith('10.1'):
|
||||
os.system(f'appdmg kcc.json dist/kcc_osx_{min_os.replace(".", "_")}_legacy_{VERSION}.dmg')
|
||||
else:
|
||||
os.system(f'appdmg kcc.json dist/kcc_macos_{platform.processor()}_{VERSION}.dmg')
|
||||
|
||||
Reference in New Issue
Block a user