diff --git a/src/calibre/ebooks/comic/input.py b/src/calibre/ebooks/comic/input.py index d144b72eae..2d3abf687a 100755 --- a/src/calibre/ebooks/comic/input.py +++ b/src/calibre/ebooks/comic/input.py @@ -89,14 +89,13 @@ class PageProcessor(list): # {{{ self.render() def render(self): - from calibre.utils.magick import Image - img = Image() - img.open(self.path_to_page) - width, height = img.size + from calibre.utils.img import image_from_data, scale_image, crop_image + with lopen(self.path_to_page, 'rb') as f: + img = image_from_data(f.read()) + width, height = img.width(), img.height() if self.num == 0: # First image so create a thumbnail from it - thumb = img.clone - thumb.thumbnail(60, 80) - thumb.save(os.path.join(self.dest, 'thumbnail.png')) + with lopen(os.path.join(self.dest, 'thumbnail.png'), 'wb') as f: + f.write(scale_image(img, as_png=True)[-1]) self.pages = [img] if width > height: if self.opts.landscape: @@ -104,29 +103,28 @@ class PageProcessor(list): # {{{ else: split1, split2 = img.clone, img.clone half = int(width/2) - split1.crop(half-1, height, 0, 0) - split2.crop(half-1, height, half, 0) + split1 = crop_image(img, 0, 0, half - 1, height) + split2 = crop_image(img, half, 0, half-1, height) self.pages = [split2, split1] if self.opts.right2left else [split1, split2] self.process_pages() def process_pages(self): - from calibre.utils.magick import PixelWand - for i, wand in enumerate(self.pages): - pw = PixelWand() - pw.color = '#ffffff' - - wand.set_border_color(pw) + from calibre.utils.img import ( + image_to_data, rotate_image, remove_borders_from_image, normalize_image, + add_borders_to_image, resize_image, gaussian_sharpen_image, grayscale_image, + despeckle_image, quantize_image + ) + for i, img in enumerate(self.pages): if self.rotate: - wand.rotate(pw, -90) + img = rotate_image(img, -90) if not self.opts.disable_trim: - wand.trim(25*65535/100) + img = remove_borders_from_image(img) - wand.set_page(0, 0, 0, 0) # Clear page after trim, like a "+repage" # Do the Photoshop "Auto Levels" equivalent if not self.opts.dont_normalize: - wand.normalize() - sizex, sizey = wand.size + img = normalize_image(img) + sizex, sizey = img.width(), img.height() SCRWIDTH, SCRHEIGHT = self.opts.output_profile.comic_screen_size @@ -153,9 +151,8 @@ class PageProcessor(list): # {{{ if newsizex < MAX_SCREEN_SIZE and newsizey < MAX_SCREEN_SIZE: # Too large and resizing fails, so better # to leave it as original size - wand.size = (newsizex, newsizey) - wand.set_border_color(pw) - wand.add_border(pw, deltax, deltay) + img = resize_image(img, newsizex, newsizey) + img = add_borders_to_image(img, left=deltax, right=deltax, top=deltay, bottom=deltay) elif self.opts.wide: # Keep aspect and Use device height as scaled image width so landscape mode is clean aspect = float(sizex) / float(sizey) @@ -177,31 +174,27 @@ class PageProcessor(list): # {{{ if newsizex < MAX_SCREEN_SIZE and newsizey < MAX_SCREEN_SIZE: # Too large and resizing fails, so better # to leave it as original size - wand.size = (newsizex, newsizey) - wand.set_border_color(pw) - wand.add_border(pw, deltax, deltay) + img = resize_image(img, newsizex, newsizey) + img = add_borders_to_image(img, left=deltax, right=deltax, top=deltay, bottom=deltay) else: if SCRWIDTH < MAX_SCREEN_SIZE and SCRHEIGHT < MAX_SCREEN_SIZE: - wand.size = (SCRWIDTH, SCRHEIGHT) + img = resize_image(img, SCRWIDTH, SCRHEIGHT) if not self.opts.dont_sharpen: - wand.sharpen(0.0, 1.0) + img = gaussian_sharpen_image(img, 0.0, 1.0) if not self.opts.dont_grayscale: - wand.type = 'GrayscaleType' + img = grayscale_image(img) if self.opts.despeckle: - wand.despeckle() + img = despeckle_image(img) - wand.quantize(self.opts.colors) + if self.opts.output_format.lower() == 'png' and self.opts.colors: + img = quantize_image(img, max_colors=min(256, self.opts.colors)) dest = '%d_%d.%s'%(self.num, i, self.opts.output_format) dest = os.path.join(self.dest, dest) - if dest.lower().endswith('.png'): - dest += '8' - wand.save(dest) - if dest.endswith('8'): - dest = dest[:-1] - os.rename(dest+'8', dest) + with lopen(dest, 'wb') as f: + f.write(image_to_data(img, fmt=self.opts.output_format)) self.append(dest) # }}} diff --git a/src/calibre/ebooks/conversion/plugins/comic_input.py b/src/calibre/ebooks/conversion/plugins/comic_input.py index daf1ff5184..e3561bbd44 100644 --- a/src/calibre/ebooks/conversion/plugins/comic_input.py +++ b/src/calibre/ebooks/conversion/plugins/comic_input.py @@ -23,10 +23,10 @@ class ComicInput(InputFormatPlugin): core_usage = -1 options = set([ - OptionRecommendation(name='colors', recommended_value=256, - help=_('Number of colors for grayscale image conversion. Default: ' - '%default. Values of less than 256 may result in blurred text ' - 'on your device if you are creating your comics in EPUB format.')), + OptionRecommendation(name='colors', recommended_value=0, + help=_('Reduce the number of colors used in the image. This works only' + ' if you choose the PNG output format. It is useful to reduce file sizes.' + ' Set to zero to turn off. Maximum value is 256. It is off by default.')), OptionRecommendation(name='dont_normalize', recommended_value=False, help=_('Disable normalize (improve contrast) color range ' 'for pictures. Default: False')), @@ -178,7 +178,8 @@ class ComicInput(InputFormatPlugin): if not os.path.exists(cdir): os.makedirs(cdir) pages = self.get_pages(fname, cdir) - if not pages: continue + if not pages: + continue wrappers = self.create_wrappers(pages) comics.append((title, pages, wrappers)) @@ -191,7 +192,8 @@ class ComicInput(InputFormatPlugin): entries = [] def href(x): - if len(comics) == 1: return os.path.basename(x) + if len(comics) == 1: + return os.path.basename(x) return '/'.join(x.split(os.sep)[-2:]) for comic in comics: