1
0
mirror of https://github.com/ciromattia/kcc synced 2025-12-13 09:46:25 +00:00

fix all other webtoon bugs (#1123)

* adjust webtoon thresholds

* fix arbitrary width webtoons

* virtual pages can exceed height by 20%

* prevent webtoon bad options

* adjust virtual page ratio

* don't change history too much

* GUI change

* add TODO

* add scroll illusion
This commit is contained in:
Alex Xu
2025-10-19 11:15:14 -07:00
committed by GitHub
parent ee8fc77ca9
commit 6f801a3334
4 changed files with 50 additions and 20 deletions

View File

@@ -719,22 +719,31 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
if value: if value:
GUI.qualityBox.setEnabled(False) GUI.qualityBox.setEnabled(False)
GUI.qualityBox.setChecked(False) GUI.qualityBox.setChecked(False)
GUI.mangaBox.setEnabled(False)
GUI.mangaBox.setChecked(False)
GUI.rotateBox.setEnabled(False) GUI.rotateBox.setEnabled(False)
GUI.rotateBox.setChecked(False) GUI.rotateBox.setChecked(False)
GUI.borderBox.setEnabled(False)
GUI.borderBox.setCheckState(Qt.CheckState.PartiallyChecked)
GUI.upscaleBox.setEnabled(False) GUI.upscaleBox.setEnabled(False)
GUI.upscaleBox.setChecked(True) GUI.upscaleBox.setChecked(False)
GUI.chunkSizeCheckBox.setEnabled(False) GUI.croppingBox.setEnabled(False)
GUI.chunkSizeCheckBox.setChecked(False) GUI.croppingBox.setChecked(False)
GUI.interPanelCropBox.setEnabled(False)
GUI.interPanelCropBox.setChecked(False)
GUI.autoLevelBox.setEnabled(False)
GUI.autoLevelBox.setChecked(False)
else: else:
profile = GUI.profiles[str(GUI.deviceBox.currentText())] profile = GUI.profiles[str(GUI.deviceBox.currentText())]
if profile['PVOptions']: if profile['PVOptions']:
GUI.qualityBox.setEnabled(True) GUI.qualityBox.setEnabled(True)
GUI.mangaBox.setEnabled(True)
GUI.rotateBox.setEnabled(True) GUI.rotateBox.setEnabled(True)
GUI.borderBox.setEnabled(True)
profile = GUI.profiles[str(GUI.deviceBox.currentText())]
if profile['Label'] != 'KS':
GUI.upscaleBox.setEnabled(True) GUI.upscaleBox.setEnabled(True)
GUI.chunkSizeCheckBox.setEnabled(True) GUI.croppingBox.setEnabled(True)
GUI.interPanelCropBox.setEnabled(True)
GUI.autoLevelBox.setEnabled(True)
def togglequalityBox(self, value): def togglequalityBox(self, value):
profile = GUI.profiles[str(GUI.deviceBox.currentText())] profile = GUI.profiles[str(GUI.deviceBox.currentText())]
@@ -801,14 +810,13 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
self.modeChange(1) self.modeChange(1)
GUI.colorBox.setChecked(profile['ForceColor']) GUI.colorBox.setChecked(profile['ForceColor'])
self.changeFormat() self.changeFormat()
GUI.gammaSlider.setValue(0)
self.changeGamma(0)
if not GUI.webtoonBox.isChecked(): if not GUI.webtoonBox.isChecked():
GUI.qualityBox.setEnabled(profile['PVOptions']) GUI.qualityBox.setEnabled(profile['PVOptions'])
GUI.upscaleBox.setChecked(profile['DefaultUpscale']) GUI.upscaleBox.setChecked(profile['DefaultUpscale'])
if profile['Label'] == 'KS': if profile['Label'] == 'KS':
GUI.upscaleBox.setDisabled(True) GUI.upscaleBox.setDisabled(True)
else: else:
if not GUI.webtoonBox.isChecked():
GUI.upscaleBox.setEnabled(True) GUI.upscaleBox.setEnabled(True)
if not profile['PVOptions']: if not profile['PVOptions']:
GUI.qualityBox.setChecked(False) GUI.qualityBox.setChecked(False)

View File

@@ -42,7 +42,6 @@ from subprocess import STDOUT, PIPE, CalledProcessError
from psutil import virtual_memory, disk_usage from psutil import virtual_memory, disk_usage
from html import escape as hescape from html import escape as hescape
import pymupdf import pymupdf
import numpy as np
from .shared import getImageFileName, walkSort, walkLevel, sanitizeTrace, subprocess_run, dot_clean from .shared import getImageFileName, walkSort, walkLevel, sanitizeTrace, subprocess_run, dot_clean
from .comicarchive import SEVENZIP, available_archive_tools from .comicarchive import SEVENZIP, available_archive_tools
@@ -1413,8 +1412,10 @@ def checkOptions(options):
if options.webtoon: if options.webtoon:
options.panelview = False options.panelview = False
options.righttoleft = False options.righttoleft = False
options.upscale = True options.upscale = False
options.hq = False options.hq = False
options.white_borders = True
options.bordersColor = 'white'
# Disable all Kindle features for other e-readers # Disable all Kindle features for other e-readers
if options.profile == 'OTHER': if options.profile == 'OTHER':
options.panelview = False options.panelview = False
@@ -1533,8 +1534,8 @@ def makeBook(source, qtgui=None):
cover = image.Cover(cover_path, options) cover = image.Cover(cover_path, options)
if options.webtoon: if options.webtoon:
y = image.ProfileData.Profiles[options.profile][1][1] x, y = image.ProfileData.Profiles[options.profile][1]
comic2panel.main(['-y ' + str(y), '-i', '-m', path], qtgui) comic2panel.main(['-y ' + str(y), '-x' + str(x), '-i', '-m', path], qtgui)
if options.noprocessing: if options.noprocessing:
print("Do not process image, ignore any profile or processing option") print("Do not process image, ignore any profile or processing option")
else: else:

View File

@@ -18,6 +18,7 @@
# PERFORMANCE OF THIS SOFTWARE. # PERFORMANCE OF THIS SOFTWARE.
# #
import math
import os import os
import sys import sys
from argparse import ArgumentParser from argparse import ArgumentParser
@@ -137,35 +138,51 @@ def splitImage(work):
panelDetected = False panelDetected = False
panelY2 = yWork panelY2 = yWork
# skip short panel at start # skip short panel at start
if not panels and panelY2 - panelY1 < v_pad * 2: if panelY1 < v_pad * 2 and panelY2 - panelY1 < v_pad * 2:
continue continue
panels.append((panelY1, panelY2, panelY2 - panelY1)) panels.append((panelY1, panelY2, panelY2 - panelY1))
yWork += v_pad // 2 yWork += v_pad // 2
max_width = 1072
virtual_width = min((max_width, opt.width, widthImg))
if opt.width > max_width:
virtual_height = int(opt.height/max_width*virtual_width)
else:
virtual_height = int(opt.height/opt.width*virtual_width)
opt.height = virtual_height
# Split too big panels # Split too big panels
panelsProcessed = [] panelsProcessed = []
for panel in panels: for panel in panels:
# 1.52 too high
if panel[2] <= opt.height * 1.5: if panel[2] <= opt.height * 1.5:
panelsProcessed.append(panel) panelsProcessed.append(panel)
elif panel[2] < opt.height * 2: elif panel[2] <= opt.height * 2:
diff = panel[2] - opt.height diff = panel[2] - opt.height
panelsProcessed.append((panel[0], panel[1] - diff, opt.height)) panelsProcessed.append((panel[0], panel[1] - diff, opt.height))
panelsProcessed.append((panel[1] - opt.height, panel[1], opt.height)) panelsProcessed.append((panel[1] - opt.height, panel[1], opt.height))
else: else:
parts = round(panel[2] / opt.height) # split super long panels with overlap
parts = math.ceil(panel[2] / opt.height)
diff = panel[2] // parts diff = panel[2] // parts
for x in range(0, parts): panelsProcessed.append((panel[0], panel[0] + opt.height, opt.height))
panelsProcessed.append((panel[0] + (x * diff), panel[1] - ((parts - x - 1) * diff), diff)) for x in range(1, parts - 1):
start = panel[0] + (x * diff)
panelsProcessed.append((start, start + opt.height, opt.height))
panelsProcessed.append((panel[1] - opt.height, panel[1], opt.height))
if opt.debug: if opt.debug:
for panel in panelsProcessed: for panel in panelsProcessed:
draw.rectangle(((0, panel[0]), (widthImg, panel[1])), (0, 255, 0, 128), (0, 0, 255, 255)) draw.rectangle(((0, panel[0]), (widthImg, panel[1])), (0, 255, 0, 128), (0, 0, 255, 255))
debugImage = Image.alpha_composite(imgOrg.convert(mode='RGBA'), drawImg) debugImage = Image.alpha_composite(imgOrg.convert(mode='RGBA'), drawImg)
# debugImage.show()
debugImage.save(os.path.join(path, os.path.splitext(name)[0] + '-debug.png'), 'PNG') debugImage.save(os.path.join(path, os.path.splitext(name)[0] + '-debug.png'), 'PNG')
# Create virtual pages # Create virtual pages
pages = [] pages = []
currentPage = [] currentPage = []
# TODO: 1.25 way too high, 1.1 too high, 1.05 slightly too high(?), optimized for 2 page landscape reading
# opt.height = max_height = virtual_height * 1.00
pageLeft = opt.height pageLeft = opt.height
panelNumber = 0 panelNumber = 0
for panel in panelsProcessed: for panel in panelsProcessed:
@@ -214,6 +231,8 @@ def main(argv=None, qtgui=None):
" with spaces.") " with spaces.")
main_options.add_argument("-y", "--height", type=int, dest="height", default=0, main_options.add_argument("-y", "--height", type=int, dest="height", default=0,
help="Height of the target device screen") help="Height of the target device screen")
main_options.add_argument("-x", "--width", type=int, dest="width", default=0,
help="Width of the target device screen")
main_options.add_argument("-i", "--in-place", action="store_true", dest="inPlace", default=False, main_options.add_argument("-i", "--in-place", action="store_true", dest="inPlace", default=False,
help="Overwrite source directory") help="Overwrite source directory")
main_options.add_argument("-m", "--merge", action="store_true", dest="merge", default=False, main_options.add_argument("-m", "--merge", action="store_true", dest="merge", default=False,

View File

@@ -397,6 +397,8 @@ class ComicPage:
self.image = Image.eval(self.image, lambda a: int(255 * (a / 255.) ** gamma)) self.image = Image.eval(self.image, lambda a: int(255 * (a / 255.) ** gamma))
def autocontrastImage(self): def autocontrastImage(self):
if self.opt.webtoon:
return
if self.opt.autolevel and not self.color: if self.opt.autolevel and not self.color:
self.convertToGrayscale() self.convertToGrayscale()
h = self.image.histogram() h = self.image.histogram()