Mercurial > libervia-backend
comparison libervia/backend/tools/image.py @ 4270:0d7bb4df2343
Reformatted code base using black.
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 19 Jun 2024 18:44:57 +0200 |
parents | 4b842c1fb686 |
children |
comparison
equal
deleted
inserted
replaced
4269:64a85ce8be70 | 4270:0d7bb4df2343 |
---|---|
30 log = getLogger(__name__) | 30 log = getLogger(__name__) |
31 | 31 |
32 try: | 32 try: |
33 import cairosvg | 33 import cairosvg |
34 except Exception as e: | 34 except Exception as e: |
35 log.warning(_("SVG support not available, please install cairosvg: {e}").format( | 35 log.warning(_("SVG support not available, please install cairosvg: {e}").format(e=e)) |
36 e=e)) | |
37 cairosvg = None | 36 cairosvg = None |
38 | 37 |
39 | 38 |
40 def check(host, path, max_size=None): | 39 def check(host, path, max_size=None): |
41 """Analyze image and return a report | 40 """Analyze image and return a report |
53 report = {} | 52 report = {} |
54 image = Image.open(path) | 53 image = Image.open(path) |
55 if max_size is None: | 54 if max_size is None: |
56 max_size = tuple(host.memory.config_get(None, "image_max", (1200, 720))) | 55 max_size = tuple(host.memory.config_get(None, "image_max", (1200, 720))) |
57 if image.size > max_size: | 56 if image.size > max_size: |
58 report['too_large'] = True | 57 report["too_large"] = True |
59 if image.size[0] > max_size[0]: | 58 if image.size[0] > max_size[0]: |
60 factor = max_size[0] / image.size[0] | 59 factor = max_size[0] / image.size[0] |
61 if image.size[1] * factor > max_size[1]: | 60 if image.size[1] * factor > max_size[1]: |
62 factor = max_size[1] / image.size[1] | 61 factor = max_size[1] / image.size[1] |
63 else: | 62 else: |
64 factor = max_size[1] / image.size[1] | 63 factor = max_size[1] / image.size[1] |
65 report['recommended_size'] = [int(image.width*factor), int(image.height*factor)] | 64 report["recommended_size"] = [ |
65 int(image.width * factor), | |
66 int(image.height * factor), | |
67 ] | |
66 else: | 68 else: |
67 report['too_large'] = False | 69 report["too_large"] = False |
68 | 70 |
69 return report | 71 return report |
70 | 72 |
71 | 73 |
72 def _resize_blocking(image_path, new_size, dest, fix_orientation): | 74 def _resize_blocking(image_path, new_size, dest, fix_orientation): |
77 resized = ImageOps.exif_transpose(resized) | 79 resized = ImageOps.exif_transpose(resized) |
78 | 80 |
79 if dest is None: | 81 if dest is None: |
80 dest = tempfile.NamedTemporaryFile(suffix=im_path.suffix, delete=False) | 82 dest = tempfile.NamedTemporaryFile(suffix=im_path.suffix, delete=False) |
81 elif isinstance(dest, Path): | 83 elif isinstance(dest, Path): |
82 dest = dest.open('wb') | 84 dest = dest.open("wb") |
83 | 85 |
84 with dest as f: | 86 with dest as f: |
85 resized.save(f, format=im.format) | 87 resized.save(f, format=im.format) |
86 | 88 |
87 return Path(f.name) | 89 return Path(f.name) |
100 @param fix_orientation: if True, use EXIF data to set orientation | 102 @param fix_orientation: if True, use EXIF data to set orientation |
101 @return (Path): path of the resized file. | 103 @return (Path): path of the resized file. |
102 The image at this path should be deleted after use | 104 The image at this path should be deleted after use |
103 """ | 105 """ |
104 return threads.deferToThread( | 106 return threads.deferToThread( |
105 _resize_blocking, image_path, new_size, dest, fix_orientation) | 107 _resize_blocking, image_path, new_size, dest, fix_orientation |
108 ) | |
106 | 109 |
107 | 110 |
108 def _convert_blocking(image_path, dest, extra): | 111 def _convert_blocking(image_path, dest, extra): |
109 media_type = mimetypes.guess_type(str(image_path), strict=False)[0] | 112 media_type = mimetypes.guess_type(str(image_path), strict=False)[0] |
110 | 113 |
121 name = None | 124 name = None |
122 if name: | 125 if name: |
123 try: | 126 try: |
124 filepath = Path(name) | 127 filepath = Path(name) |
125 except TypeError: | 128 except TypeError: |
126 filepath = Path('noname.png') | 129 filepath = Path("noname.png") |
127 else: | 130 else: |
128 filepath = Path('noname.png') | 131 filepath = Path("noname.png") |
129 | 132 |
130 if media_type == "image/svg+xml": | 133 if media_type == "image/svg+xml": |
131 if cairosvg is None: | 134 if cairosvg is None: |
132 raise exceptions.MissingModule( | 135 raise exceptions.MissingModule( |
133 f"Can't convert SVG image at {image_path} due to missing CairoSVG module") | 136 f"Can't convert SVG image at {image_path} due to missing CairoSVG module" |
134 width, height = extra.get('width'), extra.get('height') | 137 ) |
138 width, height = extra.get("width"), extra.get("height") | |
135 cairosvg.svg2png( | 139 cairosvg.svg2png( |
136 url=str(image_path), write_to=dest, | 140 url=str(image_path), write_to=dest, output_width=width, output_height=height |
137 output_width=width, output_height=height | |
138 ) | 141 ) |
139 else: | 142 else: |
140 suffix = filepath.suffix | 143 suffix = filepath.suffix |
141 if not suffix: | 144 if not suffix: |
142 raise ValueError( | 145 raise ValueError( |
143 "A suffix is missing for destination, it is needed to determine file " | 146 "A suffix is missing for destination, it is needed to determine file " |
144 "format") | 147 "format" |
148 ) | |
145 if not suffix in Image.EXTENSION: | 149 if not suffix in Image.EXTENSION: |
146 Image.init() | 150 Image.init() |
147 try: | 151 try: |
148 im_format = Image.EXTENSION[suffix] | 152 im_format = Image.EXTENSION[suffix] |
149 except KeyError: | 153 except KeyError: |
183 def __fix_orientation_blocking(image_path): | 187 def __fix_orientation_blocking(image_path): |
184 im = Image.open(image_path) | 188 im = Image.open(image_path) |
185 im_format = im.format | 189 im_format = im.format |
186 exif = im.getexif() | 190 exif = im.getexif() |
187 orientation = exif.get(0x0112) | 191 orientation = exif.get(0x0112) |
188 if orientation is None or orientation<2: | 192 if orientation is None or orientation < 2: |
189 # nothing to do | 193 # nothing to do |
190 return False | 194 return False |
191 im = ImageOps.exif_transpose(im) | 195 im = ImageOps.exif_transpose(im) |
192 im.save(image_path, im_format) | 196 im.save(image_path, im_format) |
193 log.debug(f"image {image_path} orientation has been fixed") | 197 log.debug(f"image {image_path} orientation has been fixed") |
216 # we first try to guess from file name | 220 # we first try to guess from file name |
217 media_type = mimetypes.guess_type(source, strict=False)[0] | 221 media_type = mimetypes.guess_type(source, strict=False)[0] |
218 if media_type is not None: | 222 if media_type is not None: |
219 return media_type | 223 return media_type |
220 | 224 |
221 # file name is not enough, we try to open it | 225 # file name is not enough, we try to open it |
222 img = Image.open(source) | 226 img = Image.open(source) |
223 try: | 227 try: |
224 return Image.MIME[img.format] | 228 return Image.MIME[img.format] |
225 except KeyError: | 229 except KeyError: |
226 return None | 230 return None |