1
0
mirror of https://github.com/ciromattia/kcc synced 2026-04-15 13:38:46 +00:00

Compare commits

...

5 Commits

Author SHA1 Message Date
Alex Xu
89cd8390da Revert "simplify removeNonImages (#1009)"
This reverts commit 69d3bf3278.
2025-07-10 13:48:45 -07:00
Alex Xu
90c9ba7539 bump 8.0.4 2025-07-10 09:19:57 -07:00
Alex Xu
84da718167 more extraction fixes (#1023) 2025-07-10 09:14:06 -07:00
Alex Xu
fe7559e6a9 Add note about RTL CBZ output 2025-07-10 06:58:03 -07:00
Alex Xu
a79c740387 don't autocontrast color content (#1021) 2025-07-09 13:59:54 -07:00
5 changed files with 33 additions and 17 deletions

View File

@@ -101,6 +101,8 @@ For flatpak, Docker, and AppImage versions, refer to the wiki: https://github.co
## FAQ
- All options have additional information in tooltips if you hover over the option.
- To get the converted book onto your Kindle/Kobo, just drag and drop the mobi/kepub into the documents folder on your Kindle/Kobo via USB
- Right to left mode not working?
- RTL mode only affects splitting order for CBZ output. Your cbz reader itself sets the page turn direction.
- Colors inverted?
- Disable Kindle dark mode
- Cannot connect Kindle Scribe or 2024+ Kindle to macOS

View File

@@ -1,4 +1,4 @@
__version__ = '8.0.3'
__version__ = '8.0.4'
__license__ = 'ISC'
__copyright__ = '2012-2022, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>, darodi'
__docformat__ = 'restructuredtext en'

View File

@@ -639,21 +639,22 @@ def imgFileProcessing(work):
workImg = image.ComicPageParser((dirpath, afile), opt)
for i in workImg.payload:
img = image.ComicPage(opt, *i)
is_not_color = not opt.forcecolor or not img.color
if is_not_color:
img.convertToGrayscale()
if opt.cropping == 2 and not opt.webtoon:
img.cropPageNumber(opt.croppingp, opt.croppingm)
if opt.cropping == 1 and not opt.webtoon:
img.cropMargin(opt.croppingp, opt.croppingm)
if opt.interpanelcrop > 0:
img.cropInterPanelEmptySections("horizontal" if opt.interpanelcrop == 1 else "both")
img.autocontrastImage()
img.gammaCorrectImage()
if is_not_color:
img.autocontrastImage()
img.resizeImage()
img.optimizeForDisplay(opt.reducerainbow)
if opt.forcecolor and img.color:
pass
elif opt.forcepng:
if is_not_color and opt.forcepng:
img.quantizeImage()
else:
img.convertToGrayscale()
output.append(img.saveToDir())
return output
except Exception:
@@ -691,6 +692,16 @@ def getWorkFolder(afile):
cbx = comicarchive.ComicArchive(afile)
path = cbx.extract(workdir)
sanitizePermissions(path)
tdir = os.listdir(workdir)
if len(tdir) == 2 and 'ComicInfo.xml' in tdir:
tdir.remove('ComicInfo.xml')
if os.path.isdir(os.path.join(workdir, tdir[0])):
os.replace(
os.path.join(workdir, 'ComicInfo.xml'),
os.path.join(workdir, tdir[0], 'ComicInfo.xml')
)
if len(tdir) == 1 and os.path.isdir(os.path.join(workdir, tdir[0])):
path = os.path.join(workdir, tdir[0])
except OSError as e:
rmtree(workdir, True)
raise UserWarning(e)
@@ -814,9 +825,6 @@ def getPanelViewSize(deviceres, size):
def removeNonImages(filetree):
# clean dot from original file
dot_clean(filetree)
for root, dirs, files in os.walk(filetree):
for name in files:
_, ext = getImageFileName(name)
@@ -880,7 +888,8 @@ def sanitizePermissions(filetree):
os.chmod(os.path.join(root, name), S_IWRITE | S_IREAD)
for name in dirs:
os.chmod(os.path.join(root, name), S_IWRITE | S_IREAD | S_IEXEC)
# clean dot from original file
dot_clean(filetree)
def dot_clean(filetree):
for root, _, files in os.walk(filetree, topdown=False):

View File

@@ -74,7 +74,7 @@ class ComicArchive:
if platform.system() == 'Darwin':
extraction_commands.append(
['unar', self.filepath, '-f', '-o', targetdir]
['unar', self.filepath, '-D', '-f', '-o', targetdir]
)
extraction_commands.reverse()
@@ -87,7 +87,7 @@ class ComicArchive:
for cmd in extraction_commands:
try:
subprocess_run(cmd, capture_output=True, check=True)
return os.path.join(targetdir, os.listdir(targetdir)[0])
return targetdir
except FileNotFoundError:
missing.append(cmd[0])
except CalledProcessError:

View File

@@ -341,16 +341,21 @@ class ComicPage:
image.save(targetPath, 'JPEG', optimize=1, quality=85)
return targetPath
def autocontrastImage(self):
def gammaCorrectImage(self):
gamma = self.opt.gamma
if gamma < 0.1:
gamma = self.gamma
if self.gamma != 1.0 and self.color:
gamma = 1.0
if gamma == 1.0:
self.image = ImageOps.autocontrast(self.image)
pass
else:
self.image = ImageOps.autocontrast(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):
# autocontrast on non grayscale images has unexpected results
# since it autocontrasts each color channel separately
self.image = ImageOps.autocontrast(self.image)
def convertToGrayscale(self):
self.image = self.image.convert('L')
@@ -358,7 +363,7 @@ class ComicPage:
def quantizeImage(self):
# remove all color pixels from image, since colorCheck() has some tolerance
# quantize with a small number of color pixels in a mostly b/w image can have unexpected results
self.image = self.image.convert("L").convert("RGB")
self.image = self.image.convert("RGB")
palImg = Image.new('P', (1, 1))
palImg.putpalette(self.palette)