Mercurial > libervia-backend
annotate sat/tools/image.py @ 3330:7b47f48d31f3
plugin XEP-0264: fix orientation of thumbnails:
Rotation of thumbnailis is now modified according to EXIF orientation data. Original image
is not modified as user may want to keep it, and orientation transformation can modify
encoding parameters.
Update `pillow` minimum version to the first one with `exif_transpose` implementation.
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 13 Aug 2020 23:46:18 +0200 |
parents | f300d78f08f3 |
children | 1512cbd6c4ac |
rev | line source |
---|---|
3066
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1 #!/usr/bin/env python3 |
3137 | 2 |
3220 | 3 # SàT: an XMPP client |
3136 | 4 # Copyright (C) 2009-2020 Jérôme Poisson (goffi@goffi.org) |
3066
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
5 |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
6 # This program is free software: you can redistribute it and/or modify |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
7 # it under the terms of the GNU Affero General Public License as published by |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
8 # the Free Software Foundation, either version 3 of the License, or |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
9 # (at your option) any later version. |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
10 |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
11 # This program is distributed in the hope that it will be useful, |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
14 # GNU Affero General Public License for more details. |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
15 |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
16 # You should have received a copy of the GNU Affero General Public License |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
18 |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
19 """Methods to manipulate images""" |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
20 |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
21 import tempfile |
3252
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
22 import mimetypes |
3066
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
23 from PIL import Image |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
24 from pathlib import Path |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
25 from twisted.internet import threads |
3259
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
26 from sat.core.i18n import _ |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
27 from sat.core import exceptions |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
28 from sat.core.log import getLogger |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
29 |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
30 log = getLogger(__name__) |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
31 |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
32 try: |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
33 import cairosvg |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
34 except Exception as e: |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
35 log.warning(_("SVG support not available, please install cairosvg: {e}").format( |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
36 e=e)) |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
37 cairosvg = None |
3066
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
38 |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
39 |
3220 | 40 def check(host, path, max_size=None): |
3066
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
41 """Analyze image and return a report |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
42 |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
43 report will indicate if image is too large, and the recommended new size if this is |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
44 the case |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
45 @param host: SàT instance |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
46 @param path(str, pathlib.Path): image to open |
3200
5c3bf37f2202
tools (images): max_size can now be manually specified in checkImage and dest in resizeImage:
Goffi <goffi@goffi.org>
parents:
3157
diff
changeset
|
47 @param max_size(tuple[int, int]): maximum accepted size of image |
5c3bf37f2202
tools (images): max_size can now be manually specified in checkImage and dest in resizeImage:
Goffi <goffi@goffi.org>
parents:
3157
diff
changeset
|
48 None to use value set in config |
3066
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
49 @return dict: report on image, with following keys: |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
50 - too_large: true if image is oversized |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
51 - recommended_size: if too_large is True, recommended size to use |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
52 """ |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
53 report = {} |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
54 image = Image.open(path) |
3200
5c3bf37f2202
tools (images): max_size can now be manually specified in checkImage and dest in resizeImage:
Goffi <goffi@goffi.org>
parents:
3157
diff
changeset
|
55 if max_size is None: |
5c3bf37f2202
tools (images): max_size can now be manually specified in checkImage and dest in resizeImage:
Goffi <goffi@goffi.org>
parents:
3157
diff
changeset
|
56 max_size = tuple(host.memory.getConfig(None, "image_max", (1200, 720))) |
3066
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
57 if image.size > max_size: |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
58 report['too_large'] = True |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
59 if image.size[0] > max_size[0]: |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
60 factor = max_size[0] / image.size[0] |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
61 if image.size[1] * factor > max_size[1]: |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
62 factor = max_size[1] / image.size[1] |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
63 else: |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
64 factor = max_size[1] / image.size[1] |
3157
8b4354b5c05f
tools (images): fixed type for recommended_size.
Goffi <goffi@goffi.org>
parents:
3137
diff
changeset
|
65 report['recommended_size'] = [int(image.width*factor), int(image.height*factor)] |
3066
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
66 else: |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
67 report['too_large'] = False |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
68 |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
69 return report |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
70 |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
71 |
3259
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
72 def _resizeBlocking(image_path, new_size, dest): |
3066
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
73 im_path = Path(image_path) |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
74 im = Image.open(im_path) |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
75 resized = im.resize(new_size, Image.LANCZOS) |
3200
5c3bf37f2202
tools (images): max_size can now be manually specified in checkImage and dest in resizeImage:
Goffi <goffi@goffi.org>
parents:
3157
diff
changeset
|
76 |
5c3bf37f2202
tools (images): max_size can now be manually specified in checkImage and dest in resizeImage:
Goffi <goffi@goffi.org>
parents:
3157
diff
changeset
|
77 if dest is None: |
5c3bf37f2202
tools (images): max_size can now be manually specified in checkImage and dest in resizeImage:
Goffi <goffi@goffi.org>
parents:
3157
diff
changeset
|
78 dest = tempfile.NamedTemporaryFile(suffix=im_path.suffix, delete=False) |
5c3bf37f2202
tools (images): max_size can now be manually specified in checkImage and dest in resizeImage:
Goffi <goffi@goffi.org>
parents:
3157
diff
changeset
|
79 elif isinstance(dest, Path): |
3220 | 80 dest = dest.open('wb') |
3200
5c3bf37f2202
tools (images): max_size can now be manually specified in checkImage and dest in resizeImage:
Goffi <goffi@goffi.org>
parents:
3157
diff
changeset
|
81 |
5c3bf37f2202
tools (images): max_size can now be manually specified in checkImage and dest in resizeImage:
Goffi <goffi@goffi.org>
parents:
3157
diff
changeset
|
82 with dest as f: |
3066
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
83 resized.save(f, format=im.format) |
3200
5c3bf37f2202
tools (images): max_size can now be manually specified in checkImage and dest in resizeImage:
Goffi <goffi@goffi.org>
parents:
3157
diff
changeset
|
84 |
3066
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
85 return Path(f.name) |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
86 |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
87 |
3220 | 88 def resize(image_path, new_size, dest=None): |
3200
5c3bf37f2202
tools (images): max_size can now be manually specified in checkImage and dest in resizeImage:
Goffi <goffi@goffi.org>
parents:
3157
diff
changeset
|
89 """Resize an image to a new file, and return its path |
3066
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
90 |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
91 @param image_path(str, Path): path of the original image |
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
92 @param new_size(tuple[int, int]): size to use for new image |
3200
5c3bf37f2202
tools (images): max_size can now be manually specified in checkImage and dest in resizeImage:
Goffi <goffi@goffi.org>
parents:
3157
diff
changeset
|
93 @param dest(None, Path, file): where the resized image must be stored, can be: |
5c3bf37f2202
tools (images): max_size can now be manually specified in checkImage and dest in resizeImage:
Goffi <goffi@goffi.org>
parents:
3157
diff
changeset
|
94 - None: use a temporary file |
3259
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
95 file will be converted to PNG |
3200
5c3bf37f2202
tools (images): max_size can now be manually specified in checkImage and dest in resizeImage:
Goffi <goffi@goffi.org>
parents:
3157
diff
changeset
|
96 - Path: path to the file to create/overwrite |
5c3bf37f2202
tools (images): max_size can now be manually specified in checkImage and dest in resizeImage:
Goffi <goffi@goffi.org>
parents:
3157
diff
changeset
|
97 - file: a file object which must be opened for writing in binary mode |
5c3bf37f2202
tools (images): max_size can now be manually specified in checkImage and dest in resizeImage:
Goffi <goffi@goffi.org>
parents:
3157
diff
changeset
|
98 @return (Path): path of the resized file. |
5c3bf37f2202
tools (images): max_size can now be manually specified in checkImage and dest in resizeImage:
Goffi <goffi@goffi.org>
parents:
3157
diff
changeset
|
99 The image at this path should be deleted after use |
3066
2cc2f65379f7
core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
100 """ |
3220 | 101 return threads.deferToThread(_resizeBlocking, image_path, new_size, dest) |
3252
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
102 |
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
103 |
3259
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
104 def _convertBlocking(image_path, dest, extra): |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
105 media_type = mimetypes.guess_type(str(image_path), strict=False)[0] |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
106 |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
107 if dest is None: |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
108 dest = tempfile.NamedTemporaryFile(suffix=".png", delete=False) |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
109 filepath = Path(dest.name) |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
110 elif isinstance(dest, Path): |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
111 filepath = dest |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
112 else: |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
113 # we should have a file-like object |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
114 try: |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
115 name = dest.name |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
116 except AttributeError: |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
117 name = None |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
118 if name: |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
119 try: |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
120 filepath = Path(name) |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
121 except TypeError: |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
122 filepath = Path('noname.png') |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
123 else: |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
124 filepath = Path('noname.png') |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
125 |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
126 if media_type == "image/svg+xml": |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
127 if cairosvg is None: |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
128 raise exceptions.MissingModule( |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
129 f"Can't convert SVG image at {image_path} due to missing CairoSVG module") |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
130 width, height = extra.get('width'), extra.get('height') |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
131 cairosvg.svg2png( |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
132 url=str(image_path), write_to=dest, |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
133 output_width=width, output_height=height |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
134 ) |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
135 else: |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
136 suffix = filepath.suffix |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
137 if not suffix: |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
138 raise ValueError( |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
139 "A suffix is missing for destination, it is needed to determine file " |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
140 "format") |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
141 if not suffix in Image.EXTENSION: |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
142 Image.init() |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
143 try: |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
144 im_format = Image.EXTENSION[suffix] |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
145 except KeyError: |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
146 raise ValueError( |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
147 "Dest image format can't be determined, {suffix!r} suffix is unknown" |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
148 ) |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
149 im = Image.open(image_path) |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
150 im.save(dest, format=im_format) |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
151 |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
152 log.debug(f"image {image_path} has been converted to {filepath}") |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
153 return filepath |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
154 |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
155 |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
156 def convert(image_path, dest=None, extra=None): |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
157 """Convert an image to a new file, and return its path |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
158 |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
159 @param image_path(str, Path): path of the image to convert |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
160 @param dest(None, Path, file): where the converted image must be stored, can be: |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
161 - None: use a temporary file |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
162 - Path: path to the file to create/overwrite |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
163 - file: a file object which must be opened for writing in binary mode |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
164 @param extra(None, dict): conversion options |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
165 if image_path link to a SVG file, following options can be used: |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
166 - width: destination width |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
167 - height: destination height |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
168 @return (Path): path of the converted file. |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
169 a generic name is used if dest is an unnamed file like object |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
170 """ |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
171 image_path = Path(image_path) |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
172 if not image_path.is_file(): |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
173 raise ValueError(f"There is no file at {image_path}!") |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
174 if extra is None: |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
175 extra = {} |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
176 return threads.deferToThread(_convertBlocking, image_path, dest, extra) |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
177 |
f300d78f08f3
core: image convertion + SVG support:
Goffi <goffi@goffi.org>
parents:
3252
diff
changeset
|
178 |
3252
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
179 def guess_type(source): |
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
180 """Guess image media type |
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
181 |
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
182 @param source(str, Path, file): image to guess type |
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
183 @return (str, None): media type, or None if we can't guess |
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
184 """ |
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
185 if isinstance(source, str): |
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
186 source = Path(source) |
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
187 |
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
188 if isinstance(source, Path): |
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
189 # we first try to guess from file name |
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
190 media_type = mimetypes.guess_type(source, strict=False)[0] |
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
191 if media_type is not None: |
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
192 return media_type |
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
193 |
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
194 # file name is not enough, we try to open it |
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
195 img = Image.open(source) |
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
196 try: |
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
197 return Image.MIME[img.format] |
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
198 except KeyError: |
54934ee3f69c
tools (image): added a guess_type method to guess media type:
Goffi <goffi@goffi.org>
parents:
3220
diff
changeset
|
199 return None |