:param image_path: path to the image :param resize_to: target size to resize this image to (largest side) :param done: optional callback :return: path and resize ratio
(image_path, resize_to, done=None)
| 99 | |
| 100 | |
| 101 | def resize_image(image_path, resize_to, done=None): |
| 102 | """ |
| 103 | :param image_path: path to the image |
| 104 | :param resize_to: target size to resize this image to (largest side) |
| 105 | :param done: optional callback |
| 106 | :return: path and resize ratio |
| 107 | """ |
| 108 | is_jpeg = re.match(r'.*\.jpe?g$', image_path, re.IGNORECASE) |
| 109 | path, ext = os.path.splitext(image_path) |
| 110 | resized_image_path = os.path.join(path + '.resized' + ext) |
| 111 | exiftool = None |
| 112 | |
| 113 | try: |
| 114 | with Image.open(image_path) as im: |
| 115 | width, height = im.size |
| 116 | max_side = max(width, height) |
| 117 | if max_side < resize_to: |
| 118 | logger.warning('You asked to make {} bigger ({} --> {}), but we are not going to do that.'.format(image_path, max_side, resize_to)) |
| 119 | retval = {'path': image_path, 'resize_ratio': 1} |
| 120 | if done is not None: |
| 121 | done(retval) |
| 122 | return retval |
| 123 | |
| 124 | ratio = float(resize_to) / float(max_side) |
| 125 | resized_width = int(width * ratio) |
| 126 | resized_height = int(height * ratio) |
| 127 | xmp = im.info.get("xmp") |
| 128 | exif = im.info.get("exif") |
| 129 | |
| 130 | resized = im.resize((resized_width, resized_height), Image.LANCZOS) |
| 131 | params = {} |
| 132 | if is_jpeg: |
| 133 | params['quality'] = 100 |
| 134 | |
| 135 | if is_jpeg: |
| 136 | if exif is not None: |
| 137 | params['exif'] = exif |
| 138 | if xmp is not None: |
| 139 | params['xmp'] = xmp |
| 140 | else: |
| 141 | # For TIFFs, we need to use exiftool |
| 142 | exiftool = shutil.which('exiftool') |
| 143 | if not exiftool: |
| 144 | raise Exception("Exiftool missing, but needed") |
| 145 | |
| 146 | resized.save(resized_image_path, **params) |
| 147 | |
| 148 | if exiftool: |
| 149 | subprocess.run([exiftool, '-tagsfromfile', image_path, '-all', '-unsafe', resized_image_path, '-overwrite_original_in_place'], |
| 150 | check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) |
| 151 | subprocess.run([exiftool, '-tagsfromfile', image_path, '-xmp', resized_image_path, '-overwrite_original_in_place'], |
| 152 | check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) |
| 153 | |
| 154 | # Delete original image, rename resized image to original |
| 155 | os.remove(image_path) |
| 156 | os.rename(resized_image_path, image_path) |
| 157 | except Exception as e: |
| 158 | logger.warning("Cannot resize {}: {}.".format(image_path, str(e))) |