1
0
mirror of https://github.com/ciromattia/kcc synced 2026-03-30 13:45:34 +00:00

add pdf width box (#1270)

This commit is contained in:
Alex Xu
2026-03-13 16:28:53 -07:00
committed by GitHub
parent b4b9e41a0c
commit b5de6fd39d
6 changed files with 44 additions and 7 deletions

View File

@@ -249,6 +249,7 @@ MAIN:
PROCESSING:
-n, --noprocessing Do not modify image and ignore any profile or processing option
--pdfextract Use legacy PDF image extraction method from KCC 8 and earlier.
--pdfwidth Render vector PDFs based on device width instead of height.
-u, --upscale Resize images smaller than device's resolution
-s, --stretch Stretch images to device's resolution
-r SPLITTER, --splitter SPLITTER

View File

@@ -943,6 +943,18 @@ Eink only has 16 shades of gray so you probably don't want this.</string>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QCheckBox" name="pdfWidthBox">
<property name="toolTip">
<string>Render vector PDFs to device width instead of height.
Useful if you plan to crop a little off the top and bottom to fill screen.</string>
</property>
<property name="text">
<string>PDF Width Render</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View File

@@ -329,6 +329,8 @@ class WorkerThread(QThread):
options.noprocessing = True
if GUI.pdfExtractBox.isChecked():
options.pdfextract = True
if GUI.pdfWidthBox.isChecked():
options.pdfwidth = True
if GUI.coverFillBox.isChecked():
options.coverfill = True
if GUI.metadataTitleBox.checkState() == Qt.CheckState.PartiallyChecked:
@@ -888,6 +890,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
self.addMessage('Colorsoft MOBI/EPUB can have blank pages. Just go back a few pages, exit, and reenter book.', 'info')
break
elif profile['Label'] == 'KDX':
GUI.mozJpegBox.setCheckState(Qt.CheckState.PartiallyChecked)
GUI.borderBox.setCheckState(Qt.CheckState.PartiallyChecked)
if not profile['PVOptions']:
GUI.qualityBox.setChecked(False)
@@ -1044,6 +1047,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
'eraseRainbowBox': GUI.eraseRainbowBox.checkState(),
'disableProcessingBox': GUI.disableProcessingBox.checkState(),
'pdfExtractBox': GUI.pdfExtractBox.checkState(),
'pdfWidthBox': GUI.pdfWidthBox.checkState(),
'coverFillBox': GUI.coverFillBox.checkState(),
'metadataTitleBox': GUI.metadataTitleBox.checkState(),
'mozJpegBox': GUI.mozJpegBox.checkState(),

View File

@@ -482,6 +482,11 @@ class Ui_mainWindow(object):
self.gridLayout_2.addWidget(self.noQuantizeBox, 10, 2, 1, 1)
self.pdfWidthBox = QCheckBox(self.optionWidget)
self.pdfWidthBox.setObjectName(u"pdfWidthBox")
self.gridLayout_2.addWidget(self.pdfWidthBox, 10, 0, 1, 1)
self.gridLayout.addWidget(self.optionWidget, 5, 0, 1, 2)
@@ -777,6 +782,12 @@ class Ui_mainWindow(object):
"Eink only has 16 shades of gray so you probably don't want this.", None))
#endif // QT_CONFIG(tooltip)
self.noQuantizeBox.setText(QCoreApplication.translate("mainWindow", u"No Quantize", None))
#if QT_CONFIG(tooltip)
self.pdfWidthBox.setToolTip(QCoreApplication.translate("mainWindow", u"Render vector PDFs to device width instead of height.\n"
"\n"
"Useful if you plan to crop a little off the top and bottom to fill screen.", None))
#endif // QT_CONFIG(tooltip)
self.pdfWidthBox.setText(QCoreApplication.translate("mainWindow", u"PDF Width Render", None))
self.gammaLabel.setText(QCoreApplication.translate("mainWindow", u"Gamma: Auto", None))
self.jpegQualityLabel.setText(QCoreApplication.translate("mainWindow", u"JPEG Quality:", None))
# retranslateUi

View File

@@ -744,7 +744,9 @@ def render_page(vector):
cpu = vector[1] # number of CPUs
filename = vector[2] # document filename
output_dir = vector[3]
target_height = vector[4]
target_width = vector[4]
target_height = vector[5]
pdf_width = vector[6]
with pymupdf.open(filename) as doc: # open the document
num_pages = doc.page_count # get number of pages
@@ -755,7 +757,10 @@ def render_page(vector):
for i in range(seg_from, seg_to): # work through our page segment
page = doc[i]
zoom = target_height / page.rect.height
if not pdf_width or page.rect.width > page.rect.height:
zoom = target_height / page.rect.height
else:
zoom = target_width / page.rect.width
mat = pymupdf.Matrix(zoom, zoom)
# TODO: decide colorspace earlier so later color check is cheaper.
# This is actually pretty hard when you have to deal with color vector text
@@ -820,7 +825,7 @@ def extract_page(vector):
def mupdf_pdf_process_pages_parallel(filename, output_dir, target_height):
def mupdf_pdf_process_pages_parallel(filename, output_dir, target_width, target_height):
render = False
with pymupdf.open(filename) as doc:
for page in doc:
@@ -840,7 +845,7 @@ def mupdf_pdf_process_pages_parallel(filename, output_dir, target_height):
cpu = cpu_count()
# make vectors of arguments for the processes
vectors = [(i, cpu, filename, output_dir, target_height) for i in range(cpu)]
vectors = [(i, cpu, filename, output_dir, target_width, target_height, options.pdfwidth) for i in range(cpu)]
print("Starting %i processes for '%s'." % (cpu, filename))
@@ -885,13 +890,13 @@ def getWorkFolder(afile, workdir=None):
if njpg == 0:
raise UserWarning("Failed to extract images from PDF file.")
return workdir
target_height = options.profileData[1][1]
target_width, target_height = options.profileData[1]
if options.cropping == 1:
target_height = target_height + target_height*0.20 #Account for possible margin at the top and bottom
elif options.cropping == 2:
target_height = target_height + target_height*0.25 #Account for possible margin at the top and bottom with page number
try:
mupdf_pdf_process_pages_parallel(afile, fullPath, target_height)
mupdf_pdf_process_pages_parallel(afile, fullPath, target_width, target_height)
except Exception as e:
rmtree(path, True)
raise UserWarning(f"Failed to extract images from PDF file. {e}")
@@ -1366,6 +1371,8 @@ def makeParser():
help="Do not modify image and ignore any profile or processing option")
processing_options.add_argument("--pdfextract", action="store_true", dest="pdfextract", default=False,
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,
help="Render vector PDFs to device width instead of height.")
processing_options.add_argument("--coverfill", action="store_true", dest="coverfill", default=False,
help="Crop cover to fill screen")
processing_options.add_argument("-u", "--upscale", action="store_true", dest="upscale", default=False,

View File

@@ -507,7 +507,9 @@ class ComicPage:
elif method == Image.Resampling.BICUBIC and not self.opt.upscale:
pass
else: # if image bigger than device resolution or smaller with upscaling
if abs(ratio_image - ratio_device) < AUTO_CROP_THRESHOLD:
if self.opt.profile == 'KDX' and abs(ratio_image - ratio_device) < AUTO_CROP_THRESHOLD * 3:
self.image = ImageOps.fit(self.image, self.size, method=method)
elif abs(ratio_image - ratio_device) < AUTO_CROP_THRESHOLD:
self.image = ImageOps.fit(self.image, self.size, method=method)
elif (self.opt.format in ('CBZ', 'PDF') or self.opt.kfx) and not self.opt.white_borders:
self.image = ImageOps.pad(self.image, self.size, method=method, color=self.fill)