Mercurial > libervia-backend
diff sat/core/sat_main.py @ 3259:f300d78f08f3
core: image convertion + SVG support:
/!\ new optional dependency: CairoSVG (with installed `[SVG]` extra)
- new `convert` method in `tools.image` to save an image in an other format, with support
for SVG (when CairoSVG is available)
- new `imageConvert` method is available for frontends
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 19 Apr 2020 16:53:44 +0200 |
parents | 6cf4bd6972c2 |
children | 4240b44842bb |
line wrap: on
line diff
--- a/sat/core/sat_main.py Sun Apr 19 16:40:34 2020 +0200 +++ b/sat/core/sat_main.py Sun Apr 19 16:53:44 2020 +0200 @@ -174,6 +174,7 @@ self.bridge.register_method("imageCheck", self._imageCheck) self.bridge.register_method("imageResize", self._imageResize) self.bridge.register_method("imageGeneratePreview", self._imageGeneratePreview) + self.bridge.register_method("imageConvert", self._imageConvert) self.memory.initialized.addCallback(lambda __: defer.ensureDeferred(self._postMemoryInit())) @@ -796,6 +797,63 @@ return preview_path + def _imageConvert(self, source, dest, extra, profile_key): + client = self.getClient(profile_key) if profile_key else None + source = Path(source) + dest = None if not dest else Path(dest) + extra = data_format.deserialise(extra) + d = defer.ensureDeferred(self.imageConvert(client, source, dest, extra)) + d.addCallback(lambda dest_path: str(dest_path)) + return d + + async def imageConvert(self, client, source, dest=None, extra=None): + """Helper method to convert an image from one format to an other + + @param client(SatClient, None): client to use for caching + this parameter is only used if dest is None + if client is None, common cache will be used insted of profile cache + @param source(Path): path to the image to convert + @param dest(None, Path, file): where to save the converted file + - None: use a cache file (uid generated from hash of source) + file will be converted to PNG + - Path: path to the file to create/overwrite + - file: a file object which must be opened for writing in binary mode + @param extra(dict, None): conversion options + see [image.convert] for details + @return (Path): path to the converted image + @raise ValueError: an issue happened with source of dest + """ + if not source.is_file: + raise ValueError(f"Source file {source} doesn't exist!") + if dest is None: + # we use hash as id, to re-use potentially existing conversion + path_hash = hashlib.sha256(str(source).encode()).hexdigest() + uid = f"{source.stem}_{path_hash}_convert_png" + filename = f"{uid}.png" + if client is None: + cache = self.common_cache + else: + cache = client.cache + metadata = cache.getMetadata(uid=uid) + if metadata is not None: + # there is already a conversion for this image in cache + return metadata['path'] + else: + with cache.cacheData( + source='HOST_IMAGE_CONVERT', + uid=uid, + filename=filename) as cache_f: + + converted_path = await image.convert( + source, + dest=cache_f, + extra=extra + ) + return converted_path + else: + return await image.convert(source, dest, extra) + + # local dirs def getLocalPath(self, client, dir_name, *extra_path, **kwargs):