annotate sat/tools/image.py @ 3264:9896589487ae

tools (common/data_objects): added __iter__ to Identities
author Goffi <goffi@goffi.org>
date Sat, 25 Apr 2020 15:54:26 +0200
parents f300d78f08f3
children 1512cbd6c4ac
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3066
2cc2f65379f7 core: added imageCheck and imageResize methods:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python3
3137
559a625a236b fixed shebangs
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
2
3220
4fbea7f1e012 tools (images): methods renaming
Goffi <goffi@goffi.org>
parents: 3200
diff changeset
3 # SàT: an XMPP client
3136
9d0df638c8b4 dates update
Goffi <goffi@goffi.org>
parents: 3066
diff changeset
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
4fbea7f1e012 tools (images): methods renaming
Goffi <goffi@goffi.org>
parents: 3200
diff changeset
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
4fbea7f1e012 tools (images): methods renaming
Goffi <goffi@goffi.org>
parents: 3200
diff changeset
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
4fbea7f1e012 tools (images): methods renaming
Goffi <goffi@goffi.org>
parents: 3200
diff changeset
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
4fbea7f1e012 tools (images): methods renaming
Goffi <goffi@goffi.org>
parents: 3200
diff changeset
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