示例#1
0
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
示例#2
0
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()
示例#3
0
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
示例#4
0
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