def convert_image(url, data, sizes, grayscale, removetrans, imgtype="jpg", background="#ffffff"): export = False img = Image() img.load(data) owidth, oheight = img.size nwidth, nheight = sizes scaled, nwidth, nheight = fit_image(owidth, oheight, nwidth, nheight) if normalize_format_name(img.format) == "gif" and GifInfo(StringIO(data), CHECK_IS_ANIMATED).frameCount > 1: raise exceptions.RejectImage("Animated gifs come out purely--not going to use it.") if scaled: img.size = (nwidth, nheight) export = True if normalize_format_name(img.format) != imgtype: export = True if removetrans and img.has_transparent_pixels(): canvas = Image() canvas.create_canvas(int(img.size[0]), int(img.size[1]), unicode(background)) canvas.compose(img) img = canvas export = True if grayscale and img.type != "GrayscaleType": img.type = "GrayscaleType" export = True if export: return (img.export(convtype[imgtype]), imgtype, imagetypes[imgtype]) else: logger.debug("image used unchanged") return (data, imgtype, imagetypes[imgtype])
def create_cover(report, icons=(), cols=5, size=60, padding=8): icons = icons or tuple(default_cover_icons(cols)) rows = int(math.ceil(len(icons) / cols)) canvas = create_canvas(cols * (size + padding), rows * (size + padding), '#eeeeee') y = -size - padding // 2 x = 0 for i, icon in enumerate(icons): if i % cols == 0: y += padding + size x = padding // 2 else: x += size + padding if report and icon in report.name_map: ipath = os.path.join(report.path, report.name_map[icon]) else: ipath = I(icon, allow_user_override=False) img = Image() with open(ipath, 'rb') as f: img.load(f.read()) scaled, nwidth, nheight = fit_image(img.size[0], img.size[1], size, size) img.size = nwidth, nheight dx = (size - nwidth) // 2 canvas.compose(img, x + dx, y) return canvas.export('JPEG')
def convert_image(url,data,sizes,grayscale, removetrans,imgtype="jpg",background='#ffffff'): export = False img = Image() img.load(data) owidth, oheight = img.size nwidth, nheight = sizes scaled, nwidth, nheight = fit_image(owidth, oheight, nwidth, nheight) if scaled: img.size = (nwidth, nheight) export = True if normalize_format_name(img.format) != imgtype: export = True if removetrans and img.has_transparent_pixels(): canvas = Image() canvas.create_canvas(int(img.size[0]), int(img.size[1]), str(background)) canvas.compose(img) img = canvas export = True if grayscale and img.type != "GrayscaleType": img.type = "GrayscaleType" export = True if export: return (img.export(convtype[imgtype]),imgtype,imagetypes[imgtype]) else: logger.debug("image used unchanged") return (data,imgtype,imagetypes[imgtype])
def browse_icon(self, name='blank.png'): cherrypy.response.headers['Content-Type'] = 'image/png' cherrypy.response.headers['Last-Modified'] = self.last_modified( self.build_time) if not hasattr(self, '__browse_icon_cache__'): self.__browse_icon_cache__ = {} if name not in self.__browse_icon_cache__: if name.startswith('_'): name = sanitize_file_name2(name[1:]) try: with open(os.path.join(config_dir, 'tb_icons', name), 'rb') as f: data = f.read() except: raise cherrypy.HTTPError(404, 'no icon named: %r' % name) else: try: data = I(name, data=True) except: raise cherrypy.HTTPError(404, 'no icon named: %r' % name) img = Image() img.load(data) width, height = img.size scaled, width, height = fit_image(width, height, 48, 48) if scaled: img.size = (width, height) self.__browse_icon_cache__[name] = img.export('png') return self.__browse_icon_cache__[name]
def thumbnail(data, width=120, height=120, bgcolor='#ffffff', fmt='jpg', preserve_aspect_ratio=True, compression_quality=70): img = Image() img.load(data) owidth, oheight = img.size if width is None: width = owidth if height is None: height = oheight if not preserve_aspect_ratio: scaled = owidth > width or oheight > height nwidth = width nheight = height else: scaled, nwidth, nheight = fit_image(owidth, oheight, width, height) if scaled: img.size = (nwidth, nheight) canvas = create_canvas(img.size[0], img.size[1], bgcolor) canvas.compose(img) data = image_to_data(canvas.img, compression_quality=compression_quality) return (canvas.size[0], canvas.size[1], data)
def browse_icon(self, name="blank.png"): cherrypy.response.headers["Content-Type"] = "image/png" cherrypy.response.headers["Last-Modified"] = self.last_modified(self.build_time) if not hasattr(self, "__browse_icon_cache__"): self.__browse_icon_cache__ = {} if name not in self.__browse_icon_cache__: if name.startswith("_"): name = sanitize_file_name2(name[1:]) try: with open(os.path.join(config_dir, "tb_icons", name), "rb") as f: data = f.read() except: raise cherrypy.HTTPError(404, "no icon named: %r" % name) else: try: data = I(name, data=True) except: raise cherrypy.HTTPError(404, "no icon named: %r" % name) img = Image() img.load(data) width, height = img.size scaled, width, height = fit_image(width, height, 48, 48) if scaled: img.size = (width, height) self.__browse_icon_cache__[name] = img.export("png") return self.__browse_icon_cache__[name]
def browse_icon(self, name='blank.png'): cherrypy.response.headers['Content-Type'] = 'image/png' cherrypy.response.headers['Last-Modified'] = self.last_modified(self.build_time) if not hasattr(self, '__browse_icon_cache__'): self.__browse_icon_cache__ = {} if name not in self.__browse_icon_cache__: if name.startswith('_'): name = sanitize_file_name2(name[1:]) try: with open(os.path.join(config_dir, 'tb_icons', name), 'rb') as f: data = f.read() except: raise cherrypy.HTTPError(404, 'no icon named: %r'%name) else: try: data = I(name, data=True) except: raise cherrypy.HTTPError(404, 'no icon named: %r'%name) img = Image() img.load(data) width, height = img.size scaled, width, height = fit_image(width, height, 48, 48) if scaled: img.size = (width, height) self.__browse_icon_cache__[name] = img.export('png') return self.__browse_icon_cache__[name]
def resize_image(self, raw, base, max_width, max_height): img = Image() img.load(raw) resized, nwidth, nheight = fit_image(img.size[0], img.size[1], max_width, max_height) if resized: img.size = (nwidth, nheight) base, ext = os.path.splitext(base) base = base + '-%dx%d%s' % (max_width, max_height, ext) raw = img.export(ext[1:]) return raw, base, resized
def create_cover_page(top_lines, logo_path, width=590, height=750, bgcolor='#ffffff', output_format='jpg', texture_data=None, texture_opacity=1.0): ''' Create the standard calibre cover page and return it as a byte string in the specified output_format. ''' canvas = create_canvas(width, height, bgcolor) if texture_data and hasattr(canvas, 'texture'): texture = Image() texture.load(texture_data) texture.set_opacity(texture_opacity) canvas.texture(texture) bottom = 10 for line in top_lines: twand = create_text_wand(line.font_size, font_path=line.font_path) bottom = draw_centered_text(canvas, twand, line.text, bottom) bottom += line.bottom_margin bottom -= top_lines[-1].bottom_margin foot_font = tweaks['generate_cover_foot_font'] if not foot_font: foot_font = P('fonts/liberation/LiberationMono-Regular.ttf') vanity = create_text_arc(__appname__ + ' ' + __version__, 24, font=foot_font, bgcolor='#00000000') lwidth, lheight = vanity.size left = int(max(0, (width - lwidth) / 2.)) top = height - lheight - 10 canvas.compose(vanity, left, top) available = (width, int(top - bottom) - 20) if available[1] > 40: logo = Image() logo.open(logo_path) lwidth, lheight = logo.size scaled, lwidth, lheight = fit_image(lwidth, lheight, *available) if scaled: logo.size = (lwidth, lheight) left = int(max(0, (width - lwidth) / 2.)) top = bottom + 10 extra = int((available[1] - lheight) / 2.0) if extra > 0: top += extra canvas.compose(logo, left, top) return canvas.export(output_format)
def create_cover_page( top_lines, logo_path, width=590, height=750, bgcolor="#ffffff", output_format="jpg", texture_data=None, texture_opacity=1.0, ): """ Create the standard calibre cover page and return it as a byte string in the specified output_format. """ canvas = create_canvas(width, height, bgcolor) if texture_data and hasattr(canvas, "texture"): texture = Image() texture.load(texture_data) texture.set_opacity(texture_opacity) canvas.texture(texture) bottom = 10 for line in top_lines: twand = create_text_wand(line.font_size, font_path=line.font_path) bottom = draw_centered_text(canvas, twand, line.text, bottom) bottom += line.bottom_margin bottom -= top_lines[-1].bottom_margin foot_font = P("fonts/liberation/LiberationMono-Regular.ttf") vanity = create_text_arc(__appname__ + " " + __version__, 24, font=foot_font, bgcolor="#00000000") lwidth, lheight = vanity.size left = int(max(0, (width - lwidth) / 2.0)) top = height - lheight - 10 canvas.compose(vanity, left, top) available = (width, int(top - bottom) - 20) if available[1] > 40: logo = Image() logo.open(logo_path) lwidth, lheight = logo.size scaled, lwidth, lheight = fit_image(lwidth, lheight, *available) if scaled: logo.size = (lwidth, lheight) left = int(max(0, (width - lwidth) / 2.0)) top = bottom + 10 extra = int((available[1] - lheight) / 2.0) if extra > 0: top += extra canvas.compose(logo, left, top) return canvas.export(output_format)
def convert_image(url, data, sizes, grayscale, removetrans, imgtype="jpg", background='#ffffff'): export = False img = Image() img.load(data) owidth, oheight = img.size nwidth, nheight = sizes scaled, nwidth, nheight = fit_image(owidth, oheight, nwidth, nheight) if normalize_format_name(img.format) == "gif" and GifInfo( StringIO(data), CHECK_IS_ANIMATED).frameCount > 1: raise exceptions.RejectImage( "Animated gifs come out purely--not going to use it.") if scaled: img.size = (nwidth, nheight) export = True if normalize_format_name(img.format) != imgtype: export = True if removetrans and img.has_transparent_pixels(): canvas = Image() canvas.create_canvas(int(img.size[0]), int(img.size[1]), unicode(background)) canvas.compose(img) img = canvas export = True if grayscale and img.type != "GrayscaleType": img.type = "GrayscaleType" export = True if export: return (img.export(convtype[imgtype]), imgtype, imagetypes[imgtype]) else: logger.debug("image used unchanged") return (data, imgtype, imagetypes[imgtype])
def thumbnail(data, width=120, height=120, bgcolor='#ffffff', fmt='jpg', preserve_aspect_ratio=True, compression_quality=70): img = Image() img.load(data) owidth, oheight = img.size if not preserve_aspect_ratio: scaled = owidth > width or oheight > height nwidth = width nheight = height else: scaled, nwidth, nheight = fit_image(owidth, oheight, width, height) if scaled: img.size = (nwidth, nheight) canvas = create_canvas(img.size[0], img.size[1], bgcolor) canvas.compose(img) if fmt == 'jpg': canvas.set_compression_quality(compression_quality) return (canvas.size[0], canvas.size[1], canvas.export(fmt))
def scramble_img(self, name, scramble_dgts=False): if self.eb.mime_map[name] in OEB_RASTER_IMAGES: data = self.eb.parsed(name) oldimg = Image() oldpath = self.eb.name_to_abspath(name) try: oldimg.load(data) wid, hgt = oldimg.size except: wid, hgt = (50, 50) try: fmt = oldimg.format except: x, x, fmt = get_nameparts(name) newimg = Image() newimg.load(self.dummyimg) newimg.size = (wid, hgt) self.eb.replace(name, newimg.export(fmt.upper()))
def browse_icon(self, name='blank.png'): cherrypy.response.headers['Content-Type'] = 'image/png' cherrypy.response.headers['Last-Modified'] = self.last_modified(self.build_time) if not hasattr(self, '__browse_icon_cache__'): self.__browse_icon_cache__ = {} if name not in self.__browse_icon_cache__: try: data = I(name, data=True) except: raise cherrypy.HTTPError(404, 'no icon named: %r'%name) img = Image() img.load(data) width, height = img.size scaled, width, height = fit_image(width, height, 48, 48) if scaled: img.size = (width, height) self.__browse_icon_cache__[name] = img.export('png') return self.__browse_icon_cache__[name]
def browse_icon(self, name='blank.png'): cherrypy.response.headers['Content-Type'] = 'image/png' cherrypy.response.headers['Last-Modified'] = self.last_modified( self.build_time) if not hasattr(self, '__browse_icon_cache__'): self.__browse_icon_cache__ = {} if name not in self.__browse_icon_cache__: try: data = I(name, data=True) except: raise cherrypy.HTTPError(404, 'no icon named: %r' % name) img = Image() img.load(data) width, height = img.size scaled, width, height = fit_image(width, height, 48, 48) if scaled: img.size = (width, height) self.__browse_icon_cache__[name] = img.export('png') return self.__browse_icon_cache__[name]
def HandleImage(self, imageData, imagePath): from calibre.utils.magick import Image img = Image() img.load(imageData) (x, y) = img.size if self.opts: if self.opts.snb_full_screen: SCREEN_X, SCREEN_Y = self.opts.output_profile.screen_size else: SCREEN_X, SCREEN_Y = self.opts.output_profile.comic_screen_size else: SCREEN_X = 540 SCREEN_Y = 700 # Handle big image only if x > SCREEN_X or y > SCREEN_Y: xScale = float(x) / SCREEN_X yScale = float(y) / SCREEN_Y scale = max(xScale, yScale) # TODO : intelligent image rotation # img = img.rotate(90) # x,y = y,x img.size = (x / scale, y / scale) img.save(imagePath)
def HandleImage(self, imageData, imagePath): from calibre.utils.magick import Image img = Image() img.load(imageData) (x,y) = img.size if self.opts: if self.opts.snb_full_screen: SCREEN_X, SCREEN_Y = self.opts.output_profile.screen_size else: SCREEN_X, SCREEN_Y = self.opts.output_profile.comic_screen_size else: SCREEN_X = 540 SCREEN_Y = 700 # Handle big image only if x > SCREEN_X or y > SCREEN_Y: xScale = float(x) / SCREEN_X yScale = float(y) / SCREEN_Y scale = max(xScale, yScale) # TODO : intelligent image rotation # img = img.rotate(90) # x,y = y,x img.size = (x / scale, y / scale) img.save(imagePath)
def create_cover_page(top_lines, bottom_lines, display_image, options, image_path, output_format='jpg'): from calibre.gui2 import ensure_app ensure_app() (width, height) = options.get(cfg.KEY_SIZE, (590, 750)) margins = options.get(cfg.KEY_MARGINS) (top_mgn, bottom_mgn, left_mgn, right_mgn, image_mgn) = ( margins['top'], margins['bottom'], margins['left'], margins['right'], margins['image']) left_mgn = min([left_mgn, (width / 2) - 10]) left_text_margin = left_mgn if left_mgn > 0 else 10 right_mgn = min([right_mgn, (width / 2) - 10]) right_text_margin = right_mgn if right_mgn > 0 else 10 colors = options[cfg.KEY_COLORS] bgcolor, border_color, fill_color, stroke_color = ( colors['background'], colors['border'], colors['fill'], colors['stroke']) if not options.get(cfg.KEY_COLOR_APPLY_STROKE, False): stroke_color = None auto_reduce_font = options.get(cfg.KEY_FONTS_AUTOREDUCED, False) borders = options[cfg.KEY_BORDERS] (cover_border_width, image_border_width) = ( borders['coverBorder'], borders['imageBorder']) is_background_image = options.get(cfg.KEY_BACKGROUND_IMAGE, False) if image_path: if not os.path.exists(image_path) or os.path.getsize(image_path) == 0: display_image = is_background_image = False canvas = create_canvas(width - cover_border_width * 2, height - cover_border_width * 2, bgcolor) if cover_border_width > 0: canvas = add_border(canvas, cover_border_width, border_color, bgcolor) if is_background_image: logo = Image() logo.open(image_path) outer_margin = 0 if cover_border_width == 0 else cover_border_width logo.size = (width - outer_margin * 2, height - outer_margin * 2) left = top = outer_margin canvas.compose(logo, int(left), int(top)) top = top_mgn if len(top_lines) > 0: for line in top_lines: twand = create_colored_text_wand(line, fill_color, stroke_color) top = draw_sized_text( canvas, twand, line, top, left_text_margin, right_text_margin, auto_reduce_font) top += line.bottom_margin top -= top_lines[-1].bottom_margin if len(bottom_lines) > 0: # Draw this on a fake canvas so can determine the space required fake_canvas = create_canvas(width, height, bgcolor) footer_height = 0 for line in bottom_lines: line.twand = create_colored_text_wand( line, fill_color, stroke_color) footer_height = draw_sized_text( fake_canvas, line.twand, line, footer_height, left_text_margin, right_text_margin, auto_reduce_font) footer_height += line.bottom_margin footer_height -= bottom_lines[-1].bottom_margin footer_top = height - footer_height - bottom_mgn bottom = footer_top # Re-use the text wand from previously which we will have adjusted the # font size on for line in bottom_lines: bottom = draw_sized_text( canvas, line.twand, line, bottom, left_text_margin, right_text_margin, auto_reduce_font=False) bottom += line.bottom_margin available = (width - (left_mgn + right_mgn), int(footer_top - top) - (image_mgn * 2)) else: available = (width - (left_mgn + right_mgn), int(height - top) - bottom_mgn - (image_mgn * 2)) if not is_background_image and display_image and available[1] > 40: logo = Image() logo.open(image_path) lwidth, lheight = logo.size available = (available[0] - image_border_width * 2, available[1] - image_border_width * 2) scaled, lwidth, lheight = fit_image(lwidth, lheight, *available) if not scaled and options.get(cfg.KEY_RESIZE_IMAGE_TO_FIT, False): scaled, lwidth, lheight = scaleup_image( lwidth, lheight, *available) if scaled: logo.size = (lwidth, lheight) if image_border_width > 0: logo = add_border(logo, image_border_width, border_color, bgcolor) left = int(max(0, (width - lwidth) / 2.)) top = top + image_mgn + ((available[1] - lheight) / 2.) canvas.compose(logo, int(left), int(top)) return canvas.export(output_format)