diff --git a/kindlecomicconverter/comic2ebook.py b/kindlecomicconverter/comic2ebook.py index de7ff46..498651b 100755 --- a/kindlecomicconverter/comic2ebook.py +++ b/kindlecomicconverter/comic2ebook.py @@ -77,7 +77,7 @@ def main(argv=None): return 0 -def buildHTML(path, imgfile, imgfilepath): +def buildHTML(path, imgfile, imgfilepath, imgfile2=None): key = pathlib.Path(imgfilepath).name filename = getImageFileName(imgfile) deviceres = options.profileData[1] @@ -103,10 +103,13 @@ def buildHTML(path, imgfile, imgfilepath): os.makedirs(htmlpath) htmlfile = os.path.join(htmlpath, filename[0] + '.xhtml') imgsize = Image.open(os.path.join(head, "Images", postfix, imgfile)).size + imgsizeframe = list(imgsize) + imgsize2 = (0, 0) + if imgfile2: + imgsize2 = Image.open(os.path.join(head, "Images", postfix, imgfile2)).size + imgsizeframe[1] += imgsize2[1] if options.hq: - imgsizeframe = (int(imgsize[0] // 1.5), int(imgsize[1] // 1.5)) - else: - imgsizeframe = imgsize + imgsizeframe = (int(imgsizeframe[0] // 1.5), int(imgsizeframe[1] // 1.5)) f = open(htmlfile, "w", encoding='UTF-8') f.writelines(["\n", "\n", @@ -115,14 +118,17 @@ def buildHTML(path, imgfile, imgfilepath): "", hescape(filename[0]), "\n", "\n", "\n" + "content=\"width=" + str(imgsizeframe[0]) + ", height=" + str(imgsizeframe[1]) + "\"/>\n" "\n", "\n", "
\n", # this display none div fixes formatting issues with virtual panel mode, for some reason '
.
\n', - "\n
\n"]) + ]) + f.write(f'') + if imgfile2: + f.write(f'') + f.write("\n\n") if options.iskindle and options.panelview: if options.autoscale: size = (getPanelViewResolution(imgsize, deviceres)) @@ -332,6 +338,10 @@ def buildOPF(dstdir, title, filelist, cover=None): mt = 'image/jpeg' f.write("\n") + if 'above' in path[1]: + bottom = path[1].replace('above', 'below') + uniqueid = uniqueid.replace('above', 'below') + f.write("\n") f.write("\n") @@ -511,10 +521,16 @@ def buildEPUB(path, chapternames, tomenumber, ischunked, cover: image.Cover, len for afile in filenames: if afile == 'cover.jpg': continue + if 'below' in afile: + continue if not chapter: chapterlist.append((dirpath.replace('Images', 'Text'), afile)) chapter = True - filelist.append(buildHTML(dirpath, afile, os.path.join(dirpath, afile))) + if 'above' in afile: + bottom = afile.replace('above', 'below') + filelist.append(buildHTML(dirpath, afile, os.path.join(dirpath, afile), bottom)) + else: + filelist.append(buildHTML(dirpath, afile, os.path.join(dirpath, afile))) build_html_end = perf_counter() print(f"buildHTML: {build_html_end - build_html_start} seconds") # Overwrite chapternames if tree is flat and ComicInfo.xml has bookmarks @@ -898,8 +914,12 @@ def chunk_process(path, mode, parent): if mode < 3: for root, dirs, files in walkLevel(path, 0): for name in files if mode == 1 else dirs: - if mode == 1: - size = os.path.getsize(os.path.join(root, name)) + size = 0 + if mode == 1: + if 'below' not in name: + size = os.path.getsize(os.path.join(root, name)) + if 'above' in name: + size += os.path.getsize(os.path.join(root, name.replace('above', 'below'))) else: size = getDirectorySize(os.path.join(root, name)) if currentSize + size > targetSize: @@ -1230,6 +1250,7 @@ def makeBook(source, qtgui=None): GUI.progressBarTick.emit('1') else: checkTools(source) + options.kindle_scribe_azw3 = options.profile == 'KS' and ('MOBI' in options.format or 'EPUB' in options.format) checkPre(source) print("Preparing source images...") path = getWorkFolder(source) diff --git a/kindlecomicconverter/image.py b/kindlecomicconverter/image.py index 8082a55..36261b4 100755 --- a/kindlecomicconverter/image.py +++ b/kindlecomicconverter/image.py @@ -286,16 +286,17 @@ class ComicPage: self.fill = fill self.rotated = False self.orgPath = os.path.join(path[0], path[1]) + self.targetPathStart = os.path.join(path[0], os.path.splitext(path[1])[0]) if 'N' in mode: - self.targetPath = os.path.join(path[0], os.path.splitext(path[1])[0]) + '-kcc' + self.targetPathEnd = '-kcc' elif 'R' in mode: - self.targetPath = os.path.join(path[0], os.path.splitext(path[1])[0]) + '-kcc-a' + self.targetPathEnd = '-kcc-a' if not options.norotate: self.rotated = True elif 'S1' in mode: - self.targetPath = os.path.join(path[0], os.path.splitext(path[1])[0]) + '-kcc-b' + self.targetPathEnd = '-kcc-b' elif 'S2' in mode: - self.targetPath = os.path.join(path[0], os.path.splitext(path[1])[0]) + '-kcc-c' + self.targetPathEnd = '-kcc-c' # backwards compatibility for Pillow >9.1.0 if not hasattr(Image, 'Resampling'): Image.Resampling = Image @@ -309,27 +310,36 @@ class ComicPage: flags.append('Rotated') if self.fill != 'white': flags.append('BlackBackground') - if self.opt.forcepng: - self.image.info["transparency"] = None - self.targetPath += '.png' - self.image.save(self.targetPath, 'PNG', optimize=1) + if self.opt.kindle_scribe_azw3 and self.image.size[1] > 1920: + w, h = self.image.size + targetPath = self.save_with_codec(self.image.crop((0, 0, w, 1920)), self.targetPathStart + '-above' + self.targetPathEnd) + self.save_with_codec(self.image.crop((0, 1920, w, h)), self.targetPathStart + '-below' + self.targetPathEnd) else: - self.targetPath += '.jpg' - if self.opt.mozjpeg: - with io.BytesIO() as output: - self.image.save(output, format="JPEG", optimize=1, quality=85) - input_jpeg_bytes = output.getvalue() - output_jpeg_bytes = mozjpeg_lossless_optimization.optimize(input_jpeg_bytes) - with open(self.targetPath, "wb") as output_jpeg_file: - output_jpeg_file.write(output_jpeg_bytes) - else: - self.image.save(self.targetPath, 'JPEG', optimize=1, quality=85) + targetPath = self.save_with_codec(self.image, self.targetPathStart + self.targetPathEnd) if os.path.isfile(self.orgPath): os.remove(self.orgPath) - return [Path(self.targetPath).name, flags] + return [Path(targetPath).name, flags] except IOError as err: raise RuntimeError('Cannot save image. ' + str(err)) + def save_with_codec(self, image, targetPath): + if self.opt.forcepng: + image.info["transparency"] = None + targetPath += '.png' + image.save(targetPath, 'PNG', optimize=1) + else: + targetPath += '.jpg' + if self.opt.mozjpeg: + with io.BytesIO() as output: + image.save(output, format="JPEG", optimize=1, quality=85) + 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) + return targetPath + def autocontrastImage(self): gamma = self.opt.gamma if gamma < 0.1: @@ -361,9 +371,6 @@ class ComicPage: self.image = self.image.filter(unsharpFilter) def resizeImage(self): - # kindle scribe conversion to mobi is limited in resolution by kindlegen, same with send to kindle and epub - if self.kindle_scribe_azw3: - self.size = (1440, 1920) ratio_device = float(self.size[1]) / float(self.size[0]) ratio_image = float(self.image.size[1]) / float(self.image.size[0]) method = self.resize_method() @@ -377,8 +384,6 @@ class ComicPage: elif (self.opt.format == 'CBZ' or self.opt.kfx) and not self.opt.white_borders: self.image = ImageOps.pad(self.image, self.size, method=method, color=self.fill) else: - if self.kindle_scribe_azw3: - self.size = (1860, 1920) self.image = ImageOps.contain(self.image, self.size, method=method) def resize_method(self): @@ -431,9 +436,8 @@ class Cover: self.crop_main_cover() size = list(self.options.profileData[1]) - if self.options.profile == 'KS': - if 'MOBI' in self.options.format or 'EPUB' in self.options.format: - size[1] = min(size[1], 1920) + if self.options.kindle_scribe_azw3: + size[1] = min(size[1], 1920) self.image.thumbnail(tuple(size), Image.Resampling.LANCZOS) def crop_main_cover(self): diff --git a/requirements.txt b/requirements.txt index 34dcfef..fda1c97 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,7 @@ requests>=2.31.0 python-slugify>=1.2.1 raven>=6.0.0 packaging>=23.2 -mozjpeg-lossless-optimization>=1.1.2 +mozjpeg-lossless-optimization==1.2.0 natsort>=8.4.0 distro>=1.8.0 numpy>=1.22.4