Mercurial > libervia-backend
comparison sat/tools/images.py @ 3200:5c3bf37f2202
tools (images): max_size can now be manually specified in checkImage and dest in resizeImage:
`context` has been removed as it is not used and doesn't seem that useful.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 01 Mar 2020 18:47:05 +0100 |
parents | 8b4354b5c05f |
children |
comparison
equal
deleted
inserted
replaced
3199:5afd7416ca2d | 3200:5c3bf37f2202 |
---|---|
19 | 19 |
20 """Methods to manipulate images""" | 20 """Methods to manipulate images""" |
21 | 21 |
22 import tempfile | 22 import tempfile |
23 from PIL import Image | 23 from PIL import Image |
24 from sat.core.constants import Const as C | |
25 from pathlib import Path | 24 from pathlib import Path |
26 from twisted.internet import threads | 25 from twisted.internet import threads |
27 | 26 |
28 | 27 |
29 def checkImage(host, path, context=C.CONTEXT_CHAT): | 28 def checkImage(host, path, max_size=None): |
30 """Analyze image and return a report | 29 """Analyze image and return a report |
31 | 30 |
32 report will indicate if image is too large, and the recommended new size if this is | 31 report will indicate if image is too large, and the recommended new size if this is |
33 the case | 32 the case |
34 @param host: SàT instance | 33 @param host: SàT instance |
35 @param path(str, pathlib.Path): image to open | 34 @param path(str, pathlib.Path): image to open |
36 @param context(str): context in which the image is transfered | 35 @param max_size(tuple[int, int]): maximum accepted size of image |
36 None to use value set in config | |
37 @return dict: report on image, with following keys: | 37 @return dict: report on image, with following keys: |
38 - too_large: true if image is oversized | 38 - too_large: true if image is oversized |
39 - recommended_size: if too_large is True, recommended size to use | 39 - recommended_size: if too_large is True, recommended size to use |
40 """ | 40 """ |
41 # TODO: context is not used yet | |
42 report = {} | 41 report = {} |
43 image = Image.open(path) | 42 image = Image.open(path) |
44 max_size = tuple(host.memory.getConfig(None, "image_max", (1200, 720))) | 43 if max_size is None: |
44 max_size = tuple(host.memory.getConfig(None, "image_max", (1200, 720))) | |
45 if image.size > max_size: | 45 if image.size > max_size: |
46 report['too_large'] = True | 46 report['too_large'] = True |
47 if image.size[0] > max_size[0]: | 47 if image.size[0] > max_size[0]: |
48 factor = max_size[0] / image.size[0] | 48 factor = max_size[0] / image.size[0] |
49 if image.size[1] * factor > max_size[1]: | 49 if image.size[1] * factor > max_size[1]: |
55 report['too_large'] = False | 55 report['too_large'] = False |
56 | 56 |
57 return report | 57 return report |
58 | 58 |
59 | 59 |
60 def _resizeImageBlocking(image_path, new_size): | 60 def _resizeImageBlocking(image_path, new_size, dest=None): |
61 im_path = Path(image_path) | 61 im_path = Path(image_path) |
62 im = Image.open(im_path) | 62 im = Image.open(im_path) |
63 resized = im.resize(new_size, Image.LANCZOS) | 63 resized = im.resize(new_size, Image.LANCZOS) |
64 with tempfile.NamedTemporaryFile(suffix=im_path.suffix, delete=False) as f: | 64 |
65 if dest is None: | |
66 dest = tempfile.NamedTemporaryFile(suffix=im_path.suffix, delete=False) | |
67 elif isinstance(dest, Path): | |
68 dest = Path.open('wb') | |
69 | |
70 with dest as f: | |
65 resized.save(f, format=im.format) | 71 resized.save(f, format=im.format) |
72 | |
66 return Path(f.name) | 73 return Path(f.name) |
67 | 74 |
68 | 75 |
69 def resizeImage(image_path, new_size): | 76 def resizeImage(image_path, new_size, dest=None): |
70 """Resize an image to a new temporary file, and return it path | 77 """Resize an image to a new file, and return its path |
71 | 78 |
72 @param image_path(str, Path): path of the original image | 79 @param image_path(str, Path): path of the original image |
73 @param new_size(tuple[int, int]): size to use for new image | 80 @param new_size(tuple[int, int]): size to use for new image |
74 @return (Path): path of the resized file. The image at this path must be deleted | 81 @param dest(None, Path, file): where the resized image must be stored, can be: |
75 after use | 82 - None: use a temporary file |
83 - Path: path to the file to create/overwrite | |
84 - file: a file object which must be opened for writing in binary mode | |
85 @return (Path): path of the resized file. | |
86 The image at this path should be deleted after use | |
76 """ | 87 """ |
77 return threads.deferToThread(_resizeImageBlocking, image_path, new_size) | 88 return threads.deferToThread(_resizeImageBlocking, image_path, new_size, dest) |