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:
@@ -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.upscaleBox.setEnabled(True)
|
GUI.borderBox.setEnabled(True)
|
||||||
GUI.chunkSizeCheckBox.setEnabled(True)
|
profile = GUI.profiles[str(GUI.deviceBox.currentText())]
|
||||||
|
if profile['Label'] != 'KS':
|
||||||
|
GUI.upscaleBox.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,15 +810,14 @@ 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:
|
||||||
GUI.upscaleBox.setEnabled(True)
|
if not GUI.webtoonBox.isChecked():
|
||||||
|
GUI.upscaleBox.setEnabled(True)
|
||||||
if not profile['PVOptions']:
|
if not profile['PVOptions']:
|
||||||
GUI.qualityBox.setChecked(False)
|
GUI.qualityBox.setChecked(False)
|
||||||
if str(GUI.deviceBox.currentText()) == 'Other':
|
if str(GUI.deviceBox.currentText()) == 'Other':
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user