# HG changeset patch # User Goffi # Date 1587308817 -7200 # Node ID b5e8e470f7f7298b9535448f635c8368570c1eaa # Parent 72290ebfaa8bcd6208918024a6912e32a4507e28 core (image): convert SVG images + better error handling: - when an SVG image is found, new backend `imageConvert` method is used to convert it to PNG - by default, 128x128 is used as dest size. - removed code to handle image without extension in filename, as it is now working with Kivy. - if texture is not updated after `texture_update` is called, an error is logged, a fallback image is used, and `on_error` event is dispatched diff -r 72290ebfaa8b -r b5e8e470f7f7 cagou/core/image.py --- a/cagou/core/image.py Sun Apr 19 17:06:45 2020 +0200 +++ b/cagou/core/image.py Sun Apr 19 17:06:57 2020 +0200 @@ -18,59 +18,57 @@ # along with this program. If not, see . -from sat.core import log as logging -log = logging.getLogger(__name__) +import mimetypes +from functools import partial from kivy.uix import image as kivy_img -from kivy.core.image import Image as CoreImage -from kivy.resources import resource_find -import io -import PIL +from sat.core import log as logging +from sat.tools.common import data_format +from cagou import G + +log = logging.getLogger(__name__) class Image(kivy_img.Image): """Image widget which accept source without extension""" + SVG_CONVERT_EXTRA = {'width': 128, 'height': 128} + + def __init__(self, **kwargs): + self.register_event_type('on_error') + super().__init__(**kwargs) + + def _imageConvertCb(self, path): + self.source = path def texture_update(self, *largs): - if not self.source: - self.texture = None - else: - filename = resource_find(self.source) - self._loops = 0 - if filename is None: - return log.error('Image: Error reading file {filename}'. - format(filename=self.source)) - mipmap = self.mipmap - if self._coreimage is not None: - self._coreimage.unbind(on_texture=self._on_tex_change) - try: - self._coreimage = ci = CoreImage(filename, mipmap=mipmap, - anim_delay=self.anim_delay, - keep_data=self.keep_data, - nocache=self.nocache) - except Exception: - # loading failed probably because of unmanaged extention, - # we try our luck with with PIL - try: - im = PIL.Image.open(filename) - ext = im.format.lower() - del im - # we can't use im.tobytes as it would use the - # internal decompressed representation from pillow - # and im.save would need processing to handle format - data = io.BytesIO(open(filename, "rb").read()) - cache_filename = "{}.{}".format(filename,ext) # needed for kivy's Image to use cache - self._coreimage = ci = CoreImage(data, ext=ext, - filename=cache_filename, mipmap=mipmap, - anim_delay=self.anim_delay, - keep_data=self.keep_data, - nocache=self.nocache) - except Exception as e: - log.warning("Can't load image: {}".format(e)) - self._coreimage = ci = None + if self.source: + if mimetypes.guess_type(self.source, strict=False)[0] == 'image/svg+xml': + log.debug(f"Converting SVG image at {self.source} to PNG") + G.host.bridge.imageConvert( + self.source, + "", + data_format.serialise(self.SVG_CONVERT_EXTRA), + "", + callback=self._imageConvertCb, + errback=partial( + G.host.errback, + message=f"Can't load image at {self.source}: {{msg}}" + ) + ) + return - if ci: - ci.bind(on_texture=self._on_tex_change) - self.texture = ci.texture + super().texture_update(*largs) + if self.source and self.texture is None: + log.warning( + f"Image {self.source} has not been imported correctly, replacing by " + f"empty one") + # FIXME: temporary image, to be replaced by something showing that something + # went wrong + self.source = G.host.app.expand( + "{media}/misc/borders/border_hollow_black.png") + self.dispatch('on_error', Exception(f"Can't load source {self.source}")) + + def on_error(self, err): + pass class AsyncImage(kivy_img.AsyncImage):