From 751e6eb4e700b0fdaf346feb1478cc5a0cb08162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Devernay?= Date: Tue, 5 Mar 2013 17:56:43 +0100 Subject: [PATCH 1/7] save dithered images as PNG, and linearize (inverse gamma) before dithering --- kcc/comic2ebook.py | 4 +++- kcc/gui.py | 14 ++++++++++++-- kcc/image.py | 9 ++++++--- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py index a6c0b51..0249a84 100755 --- a/kcc/comic2ebook.py +++ b/kcc/comic2ebook.py @@ -252,7 +252,7 @@ def isInFilelist(filename, filelist): def applyImgOptimization(img, isSplit=False, toRight=False): - img.optimizeImage() + img.optimizeImage(options.gamma) img.cropWhiteSpace(10.0) if options.cutpagenumbers: img.cutPageNumber() @@ -396,6 +396,8 @@ def main(argv=None): help="Verbose output [default=False]") parser.add_option("--no-image-processing", action="store_false", dest="imgproc", default=True, help="Do not apply image preprocessing (page splitting and optimizations) [default=True]") + parser.add_option("--gamma", type="float", dest="gamma", default=2.2, + help="Apply gamma correction to linearize the image [default=2.2]") parser.add_option("--upscale-images", action="store_true", dest="upscale", default=False, help="Resize images smaller than device's resolution [default=False]") parser.add_option("--stretch-images", action="store_true", dest="stretch", default=False, diff --git a/kcc/gui.py b/kcc/gui.py index 9f98590..c1156b4 100644 --- a/kcc/gui.py +++ b/kcc/gui.py @@ -92,6 +92,7 @@ class MainWindow: 'rotate': IntVar(None, 0), 'cut_page_numbers': IntVar(None, 1), 'mangastyle': IntVar(None, 0), + 'image_gamma': DoubleVar(None, 2.2), 'image_upscale': IntVar(None, 0), 'image_stretch': IntVar(None, 0), 'black_borders': IntVar(None, 0) @@ -102,13 +103,20 @@ class MainWindow: 'rotate': "Rotate landscape images instead of splitting them", 'cut_page_numbers': "Cut page numbers", 'mangastyle': "Manga-style (right-to-left reading, applies to reading and splitting)", + 'image_gamma': "Gamma value", 'image_upscale': "Allow image upscaling", 'image_stretch': "Stretch images", 'black_borders': "Use black borders" } for key in self.options: - aCheckButton = Checkbutton(self.master, text=self.optionlabels[key], variable=self.options[key]) - aCheckButton.grid(column=3, sticky='w') + if isinstance( self.options[key], IntVar ) or isinstance( self.options[key], BooleanVar ): + aCheckButton = Checkbutton(self.master, text=self.optionlabels[key], variable=self.options[key]) + aCheckButton.grid(column=3, sticky='w') + elif isinstance( self.options[key], DoubleVar ): + aLabel = Label(self.master, text=self.optionlabels[key]) + aLabel.grid(column=2, sticky='w') + aEntry = Entry(self.master, textvariable=self.options[key]) + aEntry.grid(column=3, row=(self.master.grid_size()[1]-1), sticky='w') self.progressbar = ttk.Progressbar(orient=HORIZONTAL, length=200, mode='determinate') self.submit = Button(self.master, text="Execute!", command=self.start_conversion, fg="red") @@ -138,6 +146,8 @@ class MainWindow: argv.append("--no-cut-page-numbers") if self.options['mangastyle'].get() == 1: argv.append("-m") + argv.append("--gamma") + argv.append(self.options['image_gamma'].get()) if self.options['image_upscale'].get() == 1: argv.append("--upscale-images") if self.options['image_stretch'].get() == 1: diff --git a/kcc/image.py b/kcc/image.py index f3080ed..00c1067 100755 --- a/kcc/image.py +++ b/kcc/image.py @@ -115,12 +115,15 @@ class ComicPage: filename = os.path.basename(self.origFileName) try: self.image = self.image.convert('L') # convert to grayscale - self.image.save(os.path.join(targetdir, filename), "JPEG") + os.remove(os.path.join(targetdir,filename)) # remove original file, copied by copytree() in comic2ebook.py +# self.image.save(os.path.join(targetdir, filename), "JPEG") + self.image.save(os.path.join(targetdir, os.path.splitext(filename)[0] + ".png"), "PNG") # quantized images don't like JPEG except IOError as e: raise RuntimeError('Cannot write image in directory %s: %s' % (targetdir, e)) - def optimizeImage(self): - self.image = ImageOps.autocontrast(self.image) + def optimizeImage(self, gamma): + self.image = ImageOps.autocontrast(Image.eval(self.image, lambda a: 255*(a/255.)**gamma)) +# self.image = ImageOps.autocontrast(self.image) def quantizeImage(self): colors = len(self.palette) / 3 From 5d3b7e83f58997898a11990254cd64821c8883a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Devernay?= Date: Tue, 5 Mar 2013 17:58:24 +0100 Subject: [PATCH 2/7] add --nosplitrotate option (is the name right?) --- kcc/comic2ebook.py | 7 ++++++- kcc/gui.py | 4 ++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py index 0249a84..1cfdd9a 100755 --- a/kcc/comic2ebook.py +++ b/kcc/comic2ebook.py @@ -277,7 +277,10 @@ def dirImgProcess(path): else: print ".", img = image.ComicPage(os.path.join(dirpath, afile), options.profile) - split = img.splitPage(dirpath, options.righttoleft, options.rotate) + if options.nosplitrotate: + split = None + else: + split = img.splitPage(dirpath, options.righttoleft, options.rotate) if split is not None: if options.verbose: print "Splitted " + afile @@ -407,6 +410,8 @@ def main(argv=None): + "is not like the device's one [default=False]") parser.add_option("--no-cut-page-numbers", action="store_false", dest="cutpagenumbers", default=True, help="Do not try to cut page numbering on images [default=True]") + parser.add_option("--nosplitrotate", action="store_true", dest="nosplitrotate", default=False, + help="Disable splitting and rotation [default=False]") parser.add_option("--rotate", action="store_true", dest="rotate", default=False, help="Rotate landscape pages instead of splitting them [default=False]") parser.add_option("-o", "--output", action="store", dest="output", default=None, diff --git a/kcc/gui.py b/kcc/gui.py index c1156b4..beb44e0 100644 --- a/kcc/gui.py +++ b/kcc/gui.py @@ -89,6 +89,7 @@ class MainWindow: self.options = { 'epub_only': IntVar(None, 0), 'image_preprocess': IntVar(None, 1), + 'nosplitrotate': IntVar(None, 0), 'rotate': IntVar(None, 0), 'cut_page_numbers': IntVar(None, 1), 'mangastyle': IntVar(None, 0), @@ -100,6 +101,7 @@ class MainWindow: self.optionlabels = { 'epub_only': "Generate ePub only (does not call 'kindlegen')", 'image_preprocess': "Apply image optimizations", + 'nosplitrotate': "Disable splitting and rotation", 'rotate': "Rotate landscape images instead of splitting them", 'cut_page_numbers': "Cut page numbers", 'mangastyle': "Manga-style (right-to-left reading, applies to reading and splitting)", @@ -140,6 +142,8 @@ class MainWindow: argv = ["-p", profilekey] if self.options['image_preprocess'].get() == 0: argv.append("--no-image-processing") + if self.options['nosplitrotate'].get() == 1: + argv.append("--nosplitrotate") if self.options['rotate'].get() == 1: argv.append("--rotate") if self.options['cut_page_numbers'].get() == 0: From b162425e52c4e118fe4de89371f437632c4261cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Tue, 5 Mar 2013 22:31:26 +0100 Subject: [PATCH 3/7] Added option to disable dithering --- kcc/comic2ebook.py | 5 ++++- kcc/image.py | 10 ++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py index 0c89a6c..c39ffeb 100755 --- a/kcc/comic2ebook.py +++ b/kcc/comic2ebook.py @@ -257,7 +257,8 @@ def applyImgOptimization(img, isSplit=False, toRight=False): if options.cutpagenumbers: img.cutPageNumber() img.resizeImage(options.upscale, options.stretch, options.black_borders, isSplit, toRight) - img.quantizeImage() + if not options.notquantize: + img.quantizeImage() def dirImgProcess(path): @@ -401,6 +402,8 @@ def main(argv=None): help="Do not apply image preprocessing (page splitting and optimizations) [default=True]") parser.add_option("--gamma", type="float", dest="gamma", default=2.2, help="Apply gamma correction to linearize the image [default=2.2]") + parser.add_option("--nodithering", action="store_true", dest="notquantize", default=False, + help="Disable image quantization [default=False]") parser.add_option("--upscale-images", action="store_true", dest="upscale", default=False, help="Resize images smaller than device's resolution [default=False]") parser.add_option("--stretch-images", action="store_true", dest="stretch", default=False, diff --git a/kcc/image.py b/kcc/image.py index 00c1067..e856d81 100755 --- a/kcc/image.py +++ b/kcc/image.py @@ -115,15 +115,17 @@ class ComicPage: filename = os.path.basename(self.origFileName) try: self.image = self.image.convert('L') # convert to grayscale - os.remove(os.path.join(targetdir,filename)) # remove original file, copied by copytree() in comic2ebook.py -# self.image.save(os.path.join(targetdir, filename), "JPEG") - self.image.save(os.path.join(targetdir, os.path.splitext(filename)[0] + ".png"), "PNG") # quantized images don't like JPEG + os.remove(os.path.join(targetdir,filename)) + if options.notquantize: + self.image.save(os.path.join(targetdir, os.path.splitext(filename)[0] + ".jpg"), "JPEG") + else: + self.image.save(os.path.join(targetdir, os.path.splitext(filename)[0] + ".png"), "PNG") except IOError as e: raise RuntimeError('Cannot write image in directory %s: %s' % (targetdir, e)) def optimizeImage(self, gamma): self.image = ImageOps.autocontrast(Image.eval(self.image, lambda a: 255*(a/255.)**gamma)) -# self.image = ImageOps.autocontrast(self.image) + def quantizeImage(self): colors = len(self.palette) / 3 From 718af10be78ea1c210de9bc5c52fc2f79a65a3f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Jastrz=C4=99bski?= Date: Tue, 5 Mar 2013 23:41:48 +0100 Subject: [PATCH 4/7] Updated GUI Plus small notquantize tweaks. --- kcc/comic2ebook.py | 6 ++--- kcc/gui.py | 59 ++++++++++++++++++++-------------------------- kcc/image.py | 4 ++-- 3 files changed, 30 insertions(+), 39 deletions(-) diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py index c39ffeb..4b71098 100755 --- a/kcc/comic2ebook.py +++ b/kcc/comic2ebook.py @@ -301,17 +301,17 @@ def dirImgProcess(path): facing = "left" img0 = image.ComicPage(split[0], options.profile) applyImgOptimization(img0, True, toRight1) - img0.saveToDir(dirpath) + img0.saveToDir(dirpath, options.notquantize) img1 = image.ComicPage(split[1], options.profile) applyImgOptimization(img1, True, toRight2) - img1.saveToDir(dirpath) + img1.saveToDir(dirpath, options.notquantize) else: if facing == "right": facing = "left" else: facing = "right" applyImgOptimization(img) - img.saveToDir(dirpath) + img.saveToDir(dirpath, options.notquantize) def genEpubStruct(path): diff --git a/kcc/gui.py b/kcc/gui.py index beb44e0..2ce2bed 100644 --- a/kcc/gui.py +++ b/kcc/gui.py @@ -40,24 +40,19 @@ class MainWindow: self.refresh_list() def open_files(self): - filetypes = [('all files', '.*'), ('Comic files', ('*.cbr', '*.cbz', '*.zip', '*.rar', '*.pdf'))] - f = tkFileDialog.askopenfilenames(title="Choose a file...", filetypes=filetypes) + filetypes = [('All files', '.*'), ('Comic files', ('*.cbr', '*.cbz', '*.zip', '*.rar', '*.pdf'))] + f = tkFileDialog.askopenfilenames(title="Choose files", filetypes=filetypes) if not isinstance(f, tuple): try: import re f = re.findall('\{(.*?)\}', f) except: - import tkMessageBox - tkMessageBox.showerror( - "Open file", - "askopenfilename() returned other than a tuple and no regex module could be found" - ) sys.exit(1) self.filelist.extend(f) self.refresh_list() def open_folder(self): - f = tkFileDialog.askdirectory(title="Choose a folder...") + f = tkFileDialog.askdirectory(title="Choose folder:") self.filelist.extend([f]) self.refresh_list() @@ -75,20 +70,21 @@ class MainWindow: self.clear_file = Button(self.master, text="Clear files", command=self.clear_files) self.clear_file.grid(row=4, column=0, rowspan=3) - self.open_file = Button(self.master, text="Add files...", command=self.open_files) + self.open_file = Button(self.master, text="Add files", command=self.open_files) self.open_file.grid(row=4, column=1, rowspan=3) - self.open_folder = Button(self.master, text="Add folder...", command=self.open_folder) + self.open_folder = Button(self.master, text="Add folder", command=self.open_folder) self.open_folder.grid(row=4, column=2, rowspan=3) self.profile = StringVar() profiles = sorted(ProfileData.ProfileLabels.iterkeys()) self.profile.set(profiles[-1]) w = apply(OptionMenu, (self.master, self.profile) + tuple(profiles)) - w.grid(row=1, column=3) + w.grid(row=4, column=3, sticky=W + E + N + S) self.options = { 'epub_only': IntVar(None, 0), 'image_preprocess': IntVar(None, 1), + 'notquantize': IntVar(None, 0), 'nosplitrotate': IntVar(None, 0), 'rotate': IntVar(None, 0), 'cut_page_numbers': IntVar(None, 1), @@ -99,13 +95,14 @@ class MainWindow: 'black_borders': IntVar(None, 0) } self.optionlabels = { - 'epub_only': "Generate ePub only (does not call 'kindlegen')", + 'epub_only': "Generate EPUB only", 'image_preprocess': "Apply image optimizations", + 'notquantize': "Disable image quantization", 'nosplitrotate': "Disable splitting and rotation", 'rotate': "Rotate landscape images instead of splitting them", 'cut_page_numbers': "Cut page numbers", - 'mangastyle': "Manga-style (right-to-left reading, applies to reading and splitting)", - 'image_gamma': "Gamma value", + 'mangastyle': "Manga mode", + 'image_gamma': "Gamma", 'image_upscale': "Allow image upscaling", 'image_stretch': "Stretch images", 'black_borders': "Use black borders" @@ -113,35 +110,31 @@ class MainWindow: for key in self.options: if isinstance( self.options[key], IntVar ) or isinstance( self.options[key], BooleanVar ): aCheckButton = Checkbutton(self.master, text=self.optionlabels[key], variable=self.options[key]) - aCheckButton.grid(column=3, sticky='w') + aCheckButton.grid(columnspan=4, sticky=W + N + S) elif isinstance( self.options[key], DoubleVar ): aLabel = Label(self.master, text=self.optionlabels[key]) - aLabel.grid(column=2, sticky='w') + aLabel.grid(column=2, sticky=W + N + S) aEntry = Entry(self.master, textvariable=self.options[key]) - aEntry.grid(column=3, row=(self.master.grid_size()[1]-1), sticky='w') - self.progressbar = ttk.Progressbar(orient=HORIZONTAL, length=200, mode='determinate') + aEntry.grid(column=3, row=(self.master.grid_size()[1]-1), sticky=W + N + S) - self.submit = Button(self.master, text="Execute!", command=self.start_conversion, fg="red") - self.submit.grid(column=3) - self.progressbar.grid(column=0, columnspan=4, sticky=W + E + N + S) - - self.notelabel = Label(self.master, - text="GUI can seem frozen while converting, kindly wait until some message appears!") - self.notelabel.grid(column=0, columnspan=4, sticky=W + E + N + S) + self.submit = Button(self.master, text="CONVERT", command=self.start_conversion, fg="red") + self.submit.grid(columnspan=4, sticky=W + E + N + S) def start_conversion(self): - self.progressbar.start() self.convert() - self.progressbar.stop() def convert(self): if len(self.filelist) < 1: - tkMessageBox.showwarning('No file selected', "You should really select some files to convert...") + tkMessageBox.showwarning('No files selected!', "Please choose files to convert.") return profilekey = ProfileData.ProfileLabels[self.profile.get()] argv = ["-p", profilekey] + argv.append("--gamma") + argv.append(self.options['image_gamma'].get()) if self.options['image_preprocess'].get() == 0: argv.append("--no-image-processing") + if self.options['notquantize'].get() == 1: + argv.append("--nodithering") if self.options['nosplitrotate'].get() == 1: argv.append("--nosplitrotate") if self.options['rotate'].get() == 1: @@ -150,8 +143,6 @@ class MainWindow: argv.append("--no-cut-page-numbers") if self.options['mangastyle'].get() == 1: argv.append("-m") - argv.append("--gamma") - argv.append(self.options['image_gamma'].get()) if self.options['image_upscale'].get() == 1: argv.append("--upscale-images") if self.options['image_stretch'].get() == 1: @@ -166,7 +157,7 @@ class MainWindow: subargv.append(entry) epub_path = comic2ebook.main(subargv) except Exception, err: - tkMessageBox.showerror('Error comic2ebook', "Error on file %s:\n%s" % (subargv[-1], str(err))) + tkMessageBox.showerror('KCC Error', "Error on file %s:\n%s" % (subargv[-1], str(err))) errors = True continue if self.options['epub_only'] == 1: @@ -178,7 +169,7 @@ class MainWindow: else: print >>sys.stderr, "Child returned", retcode except OSError as e: - tkMessageBox.showerror('Error kindlegen', "Error on file %s:\n%s" % (epub_path, e)) + tkMessageBox.showerror('KindleGen Error', "Error on file %s:\n%s" % (epub_path, e)) errors = True continue mobifile = epub_path.replace('.epub', '.mobi') @@ -193,12 +184,12 @@ class MainWindow: if errors: tkMessageBox.showinfo( "Done", - "Conversion finished (some errors have been reported)" + "Conversion failed. Errors have been reported." ) else: tkMessageBox.showinfo( "Done", - "Conversion successfully done!" + "Conversion successful!" ) def remove_readonly(self, fn, path): diff --git a/kcc/image.py b/kcc/image.py index e856d81..3cac5b2 100755 --- a/kcc/image.py +++ b/kcc/image.py @@ -111,12 +111,12 @@ class ComicPage: raise RuntimeError('Cannot read image file %s' % source) self.image = self.image.convert('RGB') - def saveToDir(self, targetdir): + def saveToDir(self, targetdir, notquantize): filename = os.path.basename(self.origFileName) try: self.image = self.image.convert('L') # convert to grayscale os.remove(os.path.join(targetdir,filename)) - if options.notquantize: + if notquantize: self.image.save(os.path.join(targetdir, os.path.splitext(filename)[0] + ".jpg"), "JPEG") else: self.image.save(os.path.join(targetdir, os.path.splitext(filename)[0] + ".png"), "PNG") From ce824f4cab95da4cf4308329245113d90c28dc05 Mon Sep 17 00:00:00 2001 From: Ciro Mattia Gonano Date: Wed, 6 Mar 2013 11:32:20 +0100 Subject: [PATCH 5/7] Add default gamma by profile support --- kcc/comic2ebook.py | 8 ++++---- kcc/gui.py | 20 ++++++++++---------- kcc/image.py | 23 ++++++++++++----------- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py index 4b71098..ebc721d 100755 --- a/kcc/comic2ebook.py +++ b/kcc/comic2ebook.py @@ -127,7 +127,7 @@ def buildNCX(dstdir, title, chapters): def buildOPF(profile, dstdir, title, filelist, cover=None, righttoleft=False): opffile = os.path.join(dstdir, 'OEBPS', 'content.opf') # read the first file resolution - profilelabel, deviceres, palette = image.ProfileData.Profiles[profile] + profilelabel, deviceres, palette, gamma = image.ProfileData.Profiles[profile] imgres = str(deviceres[0]) + "x" + str(deviceres[1]) if righttoleft: writingmode = "horizontal-rl" @@ -258,7 +258,7 @@ def applyImgOptimization(img, isSplit=False, toRight=False): img.cutPageNumber() img.resizeImage(options.upscale, options.stretch, options.black_borders, isSplit, toRight) if not options.notquantize: - img.quantizeImage() + img.quantizeImage() def dirImgProcess(path): @@ -400,8 +400,8 @@ def main(argv=None): help="Verbose output [default=False]") parser.add_option("--no-image-processing", action="store_false", dest="imgproc", default=True, help="Do not apply image preprocessing (page splitting and optimizations) [default=True]") - parser.add_option("--gamma", type="float", dest="gamma", default=2.2, - help="Apply gamma correction to linearize the image [default=2.2]") + parser.add_option("--gamma", type="float", dest="gamma", default="0.0", + help="Apply gamma correction to linearize the image [default=auto]") parser.add_option("--nodithering", action="store_true", dest="notquantize", default=False, help="Disable image quantization [default=False]") parser.add_option("--upscale-images", action="store_true", dest="upscale", default=False, diff --git a/kcc/gui.py b/kcc/gui.py index 2ce2bed..815c1dc 100644 --- a/kcc/gui.py +++ b/kcc/gui.py @@ -23,7 +23,6 @@ __docformat__ = 'restructuredtext en' from Tkinter import * import tkFileDialog import tkMessageBox -import ttk import comic2ebook import kindlestrip from image import ProfileData @@ -89,7 +88,7 @@ class MainWindow: 'rotate': IntVar(None, 0), 'cut_page_numbers': IntVar(None, 1), 'mangastyle': IntVar(None, 0), - 'image_gamma': DoubleVar(None, 2.2), + 'image_gamma': DoubleVar(None, 0.0), 'image_upscale': IntVar(None, 0), 'image_stretch': IntVar(None, 0), 'black_borders': IntVar(None, 0) @@ -102,20 +101,20 @@ class MainWindow: 'rotate': "Rotate landscape images instead of splitting them", 'cut_page_numbers': "Cut page numbers", 'mangastyle': "Manga mode", - 'image_gamma': "Gamma", + 'image_gamma': "Custom gamma\n(if 0.0 the default gamma for the profile will be used)", 'image_upscale': "Allow image upscaling", 'image_stretch': "Stretch images", 'black_borders': "Use black borders" } for key in self.options: - if isinstance( self.options[key], IntVar ) or isinstance( self.options[key], BooleanVar ): + if isinstance(self.options[key], IntVar) or isinstance(self.options[key], BooleanVar): aCheckButton = Checkbutton(self.master, text=self.optionlabels[key], variable=self.options[key]) aCheckButton.grid(columnspan=4, sticky=W + N + S) - elif isinstance( self.options[key], DoubleVar ): - aLabel = Label(self.master, text=self.optionlabels[key]) - aLabel.grid(column=2, sticky=W + N + S) + elif isinstance(self.options[key], DoubleVar): + aLabel = Label(self.master, text=self.optionlabels[key], justify=RIGHT) + aLabel.grid(column=0, columnspan=3, sticky=W + N + S) aEntry = Entry(self.master, textvariable=self.options[key]) - aEntry.grid(column=3, row=(self.master.grid_size()[1]-1), sticky=W + N + S) + aEntry.grid(column=3, row=(self.master.grid_size()[1] - 1), sticky=W + N + S) self.submit = Button(self.master, text="CONVERT", command=self.start_conversion, fg="red") self.submit.grid(columnspan=4, sticky=W + E + N + S) @@ -129,8 +128,9 @@ class MainWindow: return profilekey = ProfileData.ProfileLabels[self.profile.get()] argv = ["-p", profilekey] - argv.append("--gamma") - argv.append(self.options['image_gamma'].get()) + if self.options['image_gamma'].get() != 0.0: + argv.append("--gamma") + argv.append(self.options['image_gamma'].get()) if self.options['image_preprocess'].get() == 0: argv.append("--no-image-processing") if self.options['notquantize'].get() == 1: diff --git a/kcc/image.py b/kcc/image.py index 3cac5b2..0316e74 100755 --- a/kcc/image.py +++ b/kcc/image.py @@ -77,13 +77,13 @@ class ProfileData: ] Profiles = { - 'K1': ("Kindle", (600, 800), Palette4), - 'K2': ("Kindle 2", (600, 800), Palette15), - 'K3': ("Kindle 3/Keyboard", (600, 800), Palette16), - 'K4': ("Kindle 4/NT/Touch", (600, 800), Palette16), - 'KHD': ("Kindle Paperwhite", (758, 1024), Palette16), - 'KDX': ("Kindle DX", (824, 1200), Palette15), - 'KDXG': ("Kindle DXG", (824, 1200), Palette16) + 'K1': ("Kindle", (600, 800), Palette4, 1.8), + 'K2': ("Kindle 2", (600, 800), Palette15, 1.8), + 'K3': ("Kindle 3/Keyboard", (600, 800), Palette16, 1.8), + 'K4': ("Kindle 4/NT/Touch", (600, 800), Palette16, 1.8), + 'KHD': ("Kindle Paperwhite", (758, 1024), Palette16, 1.8), + 'KDX': ("Kindle DX", (824, 1200), Palette15, 1.8), + 'KDXG': ("Kindle DXG", (824, 1200), Palette16, 1.8) } ProfileLabels = { @@ -101,7 +101,7 @@ class ComicPage: def __init__(self, source, device): try: self.profile = device - self.profile_label, self.size, self.palette = ProfileData.Profiles[device] + self.profile_label, self.size, self.palette, self.gamma = ProfileData.Profiles[device] except KeyError: raise RuntimeError('Unexpected output device %s' % device) try: @@ -115,7 +115,7 @@ class ComicPage: filename = os.path.basename(self.origFileName) try: self.image = self.image.convert('L') # convert to grayscale - os.remove(os.path.join(targetdir,filename)) + os.remove(os.path.join(targetdir, filename)) if notquantize: self.image.save(os.path.join(targetdir, os.path.splitext(filename)[0] + ".jpg"), "JPEG") else: @@ -124,8 +124,9 @@ class ComicPage: raise RuntimeError('Cannot write image in directory %s: %s' % (targetdir, e)) def optimizeImage(self, gamma): - self.image = ImageOps.autocontrast(Image.eval(self.image, lambda a: 255*(a/255.)**gamma)) - + if gamma < 0.1: + gamma = self.gamma + self.image = ImageOps.autocontrast(Image.eval(self.image, lambda a: 255 * (a / 255.) ** gamma)) def quantizeImage(self): colors = len(self.palette) / 3 From 4cfac52d6a786383ce8adc9624e5cd53b368a78c Mon Sep 17 00:00:00 2001 From: Ciro Mattia Gonano Date: Wed, 6 Mar 2013 15:08:42 +0100 Subject: [PATCH 6/7] Display progressbars (fixes #13) Still to change into something less eye-bleeding ;) --- kcc/gui.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/kcc/gui.py b/kcc/gui.py index 815c1dc..90eaa11 100644 --- a/kcc/gui.py +++ b/kcc/gui.py @@ -23,6 +23,7 @@ __docformat__ = 'restructuredtext en' from Tkinter import * import tkFileDialog import tkMessageBox +import ttk import comic2ebook import kindlestrip from image import ProfileData @@ -118,9 +119,21 @@ class MainWindow: self.submit = Button(self.master, text="CONVERT", command=self.start_conversion, fg="red") self.submit.grid(columnspan=4, sticky=W + E + N + S) + aLabel = Label(self.master, text="file progress", justify=RIGHT) + aLabel.grid(column=0, sticky=E) + self.progress_file = ttk.Progressbar(orient=HORIZONTAL, length=200, mode='determinate', maximum=4) + self.progress_file.grid(column=1, columnspan=3, row=(self.master.grid_size()[1] - 1), sticky=W + E + N + S) + aLabel = Label(self.master, text="overall progress", justify=RIGHT) + aLabel.grid(column=0, sticky=E) + self.progress_overall = ttk.Progressbar(orient=HORIZONTAL, length=200, mode='determinate') + self.progress_overall.grid(column=1, columnspan=3, row=(self.master.grid_size()[1] - 1), sticky=W + E + N + S) def start_conversion(self): + self.submit['state'] = DISABLED + self.master.update() self.convert() + self.submit['state'] = NORMAL + self.master.update() def convert(self): if len(self.filelist) < 1: @@ -150,12 +163,20 @@ class MainWindow: if self.options['black_borders'].get() == 1: argv.append("--black-borders") errors = False + left_files = len(self.filelist) + filenum = 0 + self.progress_overall['value'] = 0 + self.progress_overall['maximum'] = left_files for entry in self.filelist: + filenum += 1 + self.progress_file['value'] = 1 self.master.update() subargv = list(argv) try: subargv.append(entry) epub_path = comic2ebook.main(subargv) + self.progress_file['value'] = 2 + self.master.update() except Exception, err: tkMessageBox.showerror('KCC Error', "Error on file %s:\n%s" % (subargv[-1], str(err))) errors = True @@ -168,6 +189,8 @@ class MainWindow: print >>sys.stderr, "Child was terminated by signal", -retcode else: print >>sys.stderr, "Child returned", retcode + self.progress_file['value'] = 3 + self.master.update() except OSError as e: tkMessageBox.showerror('KindleGen Error', "Error on file %s:\n%s" % (epub_path, e)) errors = True @@ -177,10 +200,14 @@ class MainWindow: shutil.move(mobifile, mobifile + '_tostrip') kindlestrip.main((mobifile + '_tostrip', mobifile)) os.remove(mobifile + '_tostrip') + self.progress_file['value'] = 4 + self.master.update() except Exception, err: tkMessageBox.showerror('Error', "Error on file %s:\n%s" % (mobifile, str(err))) errors = True continue + self.progress_overall['value'] = filenum + self.master.update() if errors: tkMessageBox.showinfo( "Done", From 1582d03fabf204200c4207a9319312e2a65b07e5 Mon Sep 17 00:00:00 2001 From: Ciro Mattia Gonano Date: Wed, 6 Mar 2013 15:15:24 +0100 Subject: [PATCH 7/7] Optimization: if gamma is 1.0 don't eval image --- kcc/image.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kcc/image.py b/kcc/image.py index 0316e74..8eeae69 100755 --- a/kcc/image.py +++ b/kcc/image.py @@ -126,7 +126,10 @@ class ComicPage: def optimizeImage(self, gamma): if gamma < 0.1: gamma = self.gamma - self.image = ImageOps.autocontrast(Image.eval(self.image, lambda a: 255 * (a / 255.) ** gamma)) + if gamma == 1.0: + self.image = ImageOps.autocontrast(self.image) + else: + self.image = ImageOps.autocontrast(Image.eval(self.image, lambda a: 255 * (a / 255.) ** gamma)) def quantizeImage(self): colors = len(self.palette) / 3