def get_image_from_uri(cache, url_fetcher, url, forced_mime_type=None): """Get a cairo Pattern from an image URI.""" missing = object() image = cache.get(url, missing) if image is not missing: return image try: with fetch(url_fetcher, url) as result: if 'string' in result: string = result['string'] else: string = result['file_obj'].read() mime_type = forced_mime_type or result['mime_type'] if mime_type == 'image/svg+xml': # No fallback for XML-based mimetypes as defined by MIME # Sniffing Standard, see https://mimesniff.spec.whatwg.org/ image = SVGImage(string, url) else: # Try to rely on given mimetype try: if mime_type == 'image/png': try: surface = cairocffi.ImageSurface.create_from_png( BytesIO(string)) except Exception as exception: raise ImageLoadingError.from_exception(exception) else: image = RasterImage(surface) else: image = None except ImageLoadingError: image = None # Relying on mimetype didn't work, give the image to GDK-Pixbuf if not image: if pixbuf is None: raise ImageLoadingError( 'Could not load GDK-Pixbuf. PNG and SVG are ' 'the only image formats available.') try: image = SVGImage(string, url) except: try: surface, format_name = ( pixbuf.decode_to_image_surface(string)) except pixbuf.ImageLoadingError as exception: raise ImageLoadingError(str(exception)) if format_name == 'jpeg' and CAIRO_HAS_MIME_DATA: surface.set_mime_data('image/jpeg', string) image = RasterImage(surface) except (URLFetchingError, ImageLoadingError) as exc: LOGGER.warning('Failed to load image at "%s" (%s)', url, exc) image = None cache[url] = image return image
def gdkpixbuf_loader(file_obj, string): """Load raster images with GDK-PixBuf.""" if pixbuf is None: raise OSError( 'Could not load GDK-Pixbuf. ' 'PNG and SVG are the only image formats available.') if string is None: string = file_obj.read() surface, format_name = pixbuf.decode_to_image_surface(string) if format_name == 'jpeg': surface.set_mime_data('image/jpeg', string) get_pattern = lambda: cairocffi.SurfacePattern(surface) return get_pattern, surface.get_width(), surface.get_height()
def get_image_from_uri(cache, url_fetcher, url, forced_mime_type=None): """Get a cairo Pattern from an image URI.""" missing = object() image = cache.get(url, missing) if image is not missing: return image try: with fetch(url_fetcher, url) as result: mime_type = forced_mime_type or result['mime_type'] if mime_type == 'image/svg+xml': string = (result['string'] if 'string' in result else result['file_obj'].read()) image = SVGImage(string, url) elif mime_type == 'image/png': obj = result.get('file_obj') or BytesIO(result.get('string')) try: surface = cairocffi.ImageSurface.create_from_png(obj) except Exception as exc: raise ImageLoadingError.from_exception(exc) image = RasterImage(surface) else: if pixbuf is None: raise ImageLoadingError( 'Could not load GDK-Pixbuf. ' 'PNG and SVG are the only image formats available.') string = (result['string'] if 'string' in result else result['file_obj'].read()) try: surface, format_name = ( pixbuf.decode_to_image_surface(string)) except pixbuf.ImageLoadingError as exc: raise ImageLoadingError(str(exc)) if format_name == 'jpeg' and CAIRO_HAS_MIME_DATA: surface.set_mime_data('image/jpeg', string) image = RasterImage(surface) except (URLFetchingError, ImageLoadingError) as exc: LOGGER.warning('Failed to load image at %s : %s', url, exc) image = None cache[url] = image return image
def get_image_from_uri(cache, url_fetcher, uri, forced_mime_type=None): """Get a cairo Pattern from an image URI.""" try: missing = object() image = cache.get(uri, missing) if image is not missing: return image result = url_fetcher(uri) mime_type = forced_mime_type or result['mime_type'] try: if mime_type == 'image/svg+xml': image = SVGImage( result.get('string') or result['file_obj'].read(), uri) elif mime_type == 'image/png': image = RasterImage( cairocffi.ImageSurface.create_from_png( result.get('file_obj') or BytesIO(result.get('string')))) else: if pixbuf is None: raise OSError( 'Could not load GDK-Pixbuf. ' 'PNG and SVG are the only image formats available.') string = result.get('string') or result['file_obj'].read() surface, format_name = pixbuf.decode_to_image_surface(string) if format_name == 'jpeg': surface.set_mime_data('image/jpeg', string) image = RasterImage(surface) finally: if 'file_obj' in result: try: result['file_obj'].close() except Exception: # pragma: no cover # May already be closed or something. # This is just cleanup anyway. pass except Exception as exc: LOGGER.warn('Error for image at %s : %r', uri, exc) image = None cache[uri] = image return image
def get_image_from_uri(cache, url_fetcher, uri, forced_mime_type=None): """Get a cairo Pattern from an image URI.""" try: missing = object() image = cache.get(uri, missing) if image is not missing: return image result = url_fetcher(uri) mime_type = forced_mime_type or result['mime_type'] try: if mime_type == 'image/svg+xml': image = SVGImage( result.get('string') or result['file_obj'].read(), uri) elif mime_type == 'image/png': image = RasterImage(cairocffi.ImageSurface.create_from_png( result.get('file_obj') or BytesIO(result.get('string')))) else: if pixbuf is None: raise OSError( 'Could not load GDK-Pixbuf. ' 'PNG and SVG are the only image formats available.') string = result.get('string') or result['file_obj'].read() surface, format_name = pixbuf.decode_to_image_surface(string) if format_name == 'jpeg': surface.set_mime_data('image/jpeg', string) image = RasterImage(surface) finally: if 'file_obj' in result: try: result['file_obj'].close() except Exception: # pragma: no cover # May already be closed or something. # This is just cleanup anyway. pass except Exception as exc: LOGGER.warn('Error for image at %s : %r', uri, exc) image = None cache[uri] = image return image