Mercurial > libervia-backend
annotate sat/tools/image.py @ 3285:4240b44842bb
core: getLocalPath now returns a Path
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 29 May 2020 21:02:20 +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 |