def read_image(file_name, format=None): """ Read an image into the given format. Will apply rotation and flipping if the image has such exif information. Args: file_name (str): image file path format (str): one of the supported image modes in PIL, or "BGR" Returns: image (np.ndarray): an HWC image """ with open(file_name, "rb") as f: image = Image.open(f) image = ImageOps.exif_transpose(image) # capture and ignore this bug: https://github.com/python-pillow/Pillow/issues/3973 try: image = ImageOps.exif_transpose(image) except Exception: pass if format is not None: # PIL only supports RGB, so convert to RGB and flip channels over below conversion_format = format if format == "BGR": conversion_format = "RGB" image = image.convert(conversion_format) image = np.asarray(image) if format == "BGR": # flip channels if needed image = image[:, :, ::-1] # PIL squeezes out the channel dimension for "L", so make it HWC if format == "L": image = np.expand_dims(image, -1) return image
def test_exif_transpose(self): exts = [".jpg"] if HAVE_WEBP and _webp.HAVE_WEBPANIM: exts.append(".webp") for ext in exts: base_im = Image.open("Tests/images/hopper" + ext) orientations = [base_im] for i in range(2, 9): im = Image.open("Tests/images/hopper_orientation_" + str(i) + ext) orientations.append(im) for i, orientation_im in enumerate(orientations): for im in [orientation_im, orientation_im.copy()]: # ImageFile # Image if i == 0: self.assertNotIn("exif", im.info) else: original_exif = im.info["exif"] transposed_im = ImageOps.exif_transpose(im) self.assert_image_similar(base_im, transposed_im, 17) if i == 0: self.assertNotIn("exif", im.info) else: self.assertNotEqual(transposed_im.info["exif"], original_exif) self.assertNotIn(0x0112, transposed_im.getexif()) # Repeat the operation, to test that it does not keep transposing transposed_im2 = ImageOps.exif_transpose(transposed_im) self.assert_image_equal(transposed_im2, transposed_im)
def __getitem__(self, idx): root = self.data[idx][0] item = self.data[idx][1] image = os.path.join(root, item['image']) depth = None if item['depth'] == 'None' else os.path.join(root, item['depth']) refs = dict() for ref_name in ['previous', 'next']: # , 'previous' ['stereo', 'previous', 'next']: # , 'previous', 'next' refs[ref_name] = os.path.join(root, item[ref_name]) out = dict() image = Image.open(image) image = ImageOps.exif_transpose(image) if image.mode != 'RGB': image = image.convert('RGB') if self.target_pixels > 0: scale_factor = math.sqrt(self.target_pixels / (image.width * image.height)) height = int(image.height * scale_factor) width = int(image.width * scale_factor) else: height = self.target_height width = self.target_width image = TF.resize(image, (height, width)) image = TF.to_tensor(image) out['image'] = image if depth is not None: depth = Image.open(depth) depth = ImageOps.exif_transpose(depth) depth = TF.resize(depth, (height, width), Image.NEAREST) depth = TF.to_tensor(depth).float() depth /= 256.0 mask = depth > 0.1 # mask &= depth < 80.0 depth[mask] = 1.0 / depth[mask] out['depth'] = depth for ref_name in refs: refs[ref_name] = Image.open(refs[ref_name]) refs[ref_name] = ImageOps.exif_transpose(refs[ref_name]) refs[ref_name] = TF.resize(refs[ref_name], (height, width)) if refs[ref_name].mode != 'RGB': refs[ref_name] = refs[ref_name].convert('RGB') refs[ref_name] = TF.to_tensor(refs[ref_name]) out[ref_name] = refs[ref_name] if item['GPS'] != 'None' and item['GPS_previous'] != 'None' and item['GPS_next'] != 'None': gps = util.GPS() lla_image = [float(i) for i in item['GPS'].split()] gps.set_origin(*lla_image) lla_previous = [float(i) for i in item['GPS_previous'].split()] distance_previous = np.linalg.norm(np.array(gps.lla2enu(*lla_previous)), keepdims=True) lla_next = [float(i) for i in item['GPS_next'].split()] distance_next = np.linalg.norm(np.array(gps.lla2enu(*lla_next)), keepdims=True) out['distance_previous'] = torch.from_numpy(distance_previous.astype(np.float32)) out['distance_next'] = torch.from_numpy(distance_next.astype(np.float32)) for out_item in out: out[out_item] = out[out_item].to(self.device) return out
def make_image(self, file, entry, workdir): """Make page for an image """ template = self.environ.get_template('image.tmpl') output = Path(workdir) / Path('images') / Path(entry["html_file"]) if entry['type'] == 'image': with Image.open(file) as im: im = ImageOps.exif_transpose(im) im.thumbnail(self._config.thumbnail_size) thumbfile = self.thumb_dir / Path(file.name) im.save(thumbfile) entry['thumb_width'] = im.width entry['thumb_height'] = im.height with Image.open(file) as im: im = ImageOps.exif_transpose(im) im.thumbnail(self._config.image_size) resized_file = self.image_dir / Path(file.name) im.save(resized_file) entry['image_width'] = im.width entry['image_height'] = im.height else: entry['image_height'] = self._config.image_size[1] entry['image_file'] = file.name with output.open('w') as outfile: template.stream(entry=entry, title=self.title).dump(outfile) entry['thumb'] = f"thumbs/{file.name}"
def __init__(self, imageName, imageBytes, cutterSizeX, cutterSizeY, force_png=False): self.imageBytes = imageBytes self.cutterSizeX = cutterSizeX self.cutterSizeY = cutterSizeY self.force_png = force_png if isinstance(imageBytes, bytes): self._img = PILImage.open(io.BytesIO(imageBytes)) self._img = ImageOps.exif_transpose(self._img) else: self._img = PILImage.open(imageBytes) self._img = ImageOps.exif_transpose(self._img) if self._img.mode == "P": self._img = PILImage.open(imageBytes).convert("RGBA") self.content_type = "image/png" self._format = "PNG" self.extension = "png" elif self._img.mode == "RGBA" or force_png: self.content_type = "image/png" self._format = "PNG" self.extension = "png" else: self.content_type = "image/jpeg" self._format = "JPEG" self.extension = "jpg" self.image_name = imageName self.data = None
def save_image(self) -> object: """Save the image and return the object""" ImageOps.exif_transpose(self.img) img_io = BytesIO() self.img.save(img_io, self.filetype, quality=85) image_object = File(img_io, name=self.image.name) return image_object
def test_sanity(): ImageOps.autocontrast(hopper("L")) ImageOps.autocontrast(hopper("RGB")) ImageOps.autocontrast(hopper("L"), cutoff=10) ImageOps.autocontrast(hopper("L"), cutoff=(2, 10)) ImageOps.autocontrast(hopper("L"), ignore=[0, 255]) ImageOps.autocontrast(hopper("L"), mask=hopper("L")) ImageOps.autocontrast(hopper("L"), preserve_tone=True) ImageOps.colorize(hopper("L"), (0, 0, 0), (255, 255, 255)) ImageOps.colorize(hopper("L"), "black", "white") ImageOps.pad(hopper("L"), (128, 128)) ImageOps.pad(hopper("RGB"), (128, 128)) ImageOps.contain(hopper("L"), (128, 128)) ImageOps.contain(hopper("RGB"), (128, 128)) ImageOps.crop(hopper("L"), 1) ImageOps.crop(hopper("RGB"), 1) ImageOps.deform(hopper("L"), deformer) ImageOps.deform(hopper("RGB"), deformer) ImageOps.equalize(hopper("L")) ImageOps.equalize(hopper("RGB")) ImageOps.expand(hopper("L"), 1) ImageOps.expand(hopper("RGB"), 1) ImageOps.expand(hopper("L"), 2, "blue") ImageOps.expand(hopper("RGB"), 2, "blue") ImageOps.fit(hopper("L"), (128, 128)) ImageOps.fit(hopper("RGB"), (128, 128)) ImageOps.flip(hopper("L")) ImageOps.flip(hopper("RGB")) ImageOps.grayscale(hopper("L")) ImageOps.grayscale(hopper("RGB")) ImageOps.invert(hopper("1")) ImageOps.invert(hopper("L")) ImageOps.invert(hopper("RGB")) ImageOps.mirror(hopper("L")) ImageOps.mirror(hopper("RGB")) ImageOps.posterize(hopper("L"), 4) ImageOps.posterize(hopper("RGB"), 4) ImageOps.solarize(hopper("L")) ImageOps.solarize(hopper("RGB")) ImageOps.exif_transpose(hopper("L")) ImageOps.exif_transpose(hopper("RGB"))
def test_exif_transpose(): exts = [".jpg"] if features.check("webp") and features.check("webp_anim"): exts.append(".webp") for ext in exts: with Image.open("Tests/images/hopper" + ext) as base_im: def check(orientation_im): for im in [ orientation_im, orientation_im.copy(), ]: # ImageFile # Image if orientation_im is base_im: assert "exif" not in im.info else: original_exif = im.info["exif"] transposed_im = ImageOps.exif_transpose(im) assert_image_similar(base_im, transposed_im, 17) if orientation_im is base_im: assert "exif" not in im.info else: assert transposed_im.info["exif"] != original_exif assert 0x0112 in im.getexif() assert 0x0112 not in transposed_im.getexif() # Repeat the operation to test that it does not keep transposing transposed_im2 = ImageOps.exif_transpose(transposed_im) assert_image_equal(transposed_im2, transposed_im) check(base_im) for i in range(2, 9): with Image.open("Tests/images/hopper_orientation_" + str(i) + ext) as orientation_im: check(orientation_im) # Orientation from "XML:com.adobe.xmp" info key with Image.open("Tests/images/xmp_tags_orientation.png") as im: assert im.getexif()[0x0112] == 3 transposed_im = ImageOps.exif_transpose(im) assert 0x0112 not in transposed_im.getexif() # Orientation from "Raw profile type exif" info key # This test image has been manually hexedited from exif_imagemagick.png # to have a different orientation with Image.open("Tests/images/exif_imagemagick_orientation.png") as im: assert im.getexif()[0x0112] == 3 transposed_im = ImageOps.exif_transpose(im) assert 0x0112 not in transposed_im.getexif() # Orientation set directly on Image.Exif im = hopper() im.getexif()[0x0112] = 3 transposed_im = ImageOps.exif_transpose(im) assert 0x0112 not in transposed_im.getexif()
def resize_emoji( image_data: bytes, size: int = DEFAULT_EMOJI_SIZE) -> Tuple[bytes, bool, Optional[bytes]]: # This function returns three values: # 1) Emoji image data. # 2) If emoji is gif i.e animated. # 3) If is animated then return still image data i.e first frame of gif. try: im = Image.open(io.BytesIO(image_data)) image_format = im.format if image_format == "GIF": assert isinstance(im, GifImageFile) # There are a number of bugs in Pillow.GifImagePlugin which cause # results in resized gifs being broken. To work around this we # only resize under certain conditions to minimize the chance of # creating ugly gifs. should_resize = ( im.size[0] != im.size[1] # not square or im.size[0] > MAX_EMOJI_GIF_SIZE # dimensions too large or len(image_data) > MAX_EMOJI_GIF_FILE_SIZE_BYTES # filesize too large ) # Generate a still image from the first frame. Since # we're converting the format to PNG anyway, we resize unconditionally. still_image = im.copy() still_image.seek(0) still_image = ImageOps.exif_transpose(still_image) still_image = ImageOps.fit(still_image, (size, size), Image.ANTIALIAS) out = io.BytesIO() still_image.save(out, format="PNG") still_image_data = out.getvalue() if should_resize: image_data = resize_gif(im, size) if im.n_frames > 1: return image_data, True, still_image_data else: return image_data, False, None else: # Note that this is essentially duplicated in the # still_image code path, above. im = ImageOps.exif_transpose(im) im = ImageOps.fit(im, (size, size), Image.ANTIALIAS) out = io.BytesIO() im.save(out, format=image_format) return out.getvalue(), False, None except OSError: raise BadImageError( _("Could not decode image; did you upload an image file?")) except DecompressionBombError: raise BadImageError(_("Image size exceeds limit."))
def verify_image_label(args): # Verify one image-label pair im_file, lb_file, prefix = args nm, nf, ne, nc, msg, segments = 0, 0, 0, 0, '', [] # number (missing, found, empty, corrupt), message, segments try: # verify images im = Image.open(im_file) im.verify() # PIL verify shape = exif_size(im) # image size assert (shape[0] > 9) & (shape[1] > 9), f'image size {shape} <10 pixels' assert im.format.lower() in IMG_FORMATS, f'invalid image format {im.format}' if im.format.lower() in ('jpg', 'jpeg'): with open(im_file, 'rb') as f: f.seek(-2, 2) if f.read() != b'\xff\xd9': # corrupt JPEG ImageOps.exif_transpose(Image.open(im_file)).save(im_file, 'JPEG', subsampling=0, quality=100) msg = f'{prefix}WARNING: {im_file}: corrupt JPEG restored and saved' # verify labels if os.path.isfile(lb_file): nf = 1 # label found with open(lb_file) as f: lb = [x.split() for x in f.read().strip().splitlines() if len(x)] if any(len(x) > 6 for x in lb): # is segment classes = np.array([x[0] for x in lb], dtype=np.float32) segments = [np.array(x[1:], dtype=np.float32).reshape(-1, 2) for x in lb] # (cls, xy1...) lb = np.concatenate((classes.reshape(-1, 1), segments2boxes(segments)), 1) # (cls, xywh) lb = np.array(lb, dtype=np.float32) nl = len(lb) if nl: assert lb.shape[1] == 5, f'labels require 5 columns, {lb.shape[1]} columns detected' assert (lb >= 0).all(), f'negative label values {lb[lb < 0]}' assert (lb[:, 1:] <= 1).all(), f'non-normalized or out of bounds coordinates {lb[:, 1:][lb[:, 1:] > 1]}' _, i = np.unique(lb, axis=0, return_index=True) if len(i) < nl: # duplicate row check lb = lb[i] # remove duplicates if segments: segments = segments[i] msg = f'{prefix}WARNING: {im_file}: {nl - len(i)} duplicate labels removed' else: ne = 1 # label empty lb = np.zeros((0, 5), dtype=np.float32) else: nm = 1 # label missing lb = np.zeros((0, 5), dtype=np.float32) return im_file, lb, shape, segments, nm, nf, ne, nc, msg except Exception as e: nc = 1 msg = f'{prefix}WARNING: {im_file}: ignoring corrupt image/label: {e}' return [None, None, None, None, nm, nf, ne, nc, msg]
async def get_photo(*, db: Session = Depends(deps.get_db), current_user: models.User = Depends( deps.check_session_and_csrf), id: int, size: int): recipe = _get(db, current_user.id, id) if not recipe.photo: raise not_found_ex photo_path = crud.recipe.get_photo_path(recipe.photo) if size <= 0: return FileResponse(photo_path) thumb_name = f"{recipe.photo}-{size}" thumb_path = crud.recipe.get_photo_path(thumb_name) if os.path.exists(thumb_path): return FileResponse(thumb_path, media_type="image/webp") print(f"Create thumbnail: {thumb_path}") with Image.open(photo_path) as img: if img.mode != "RGB": img = img.convert("RGB") img = ImageOps.exif_transpose(img) img.thumbnail((size, size)) img.save(thumb_path, format="WEBP", quality=80) return FileResponse(thumb_path, media_type="image/webp")
def __process_tile(self, tile_path): try: img = Image.open(tile_path) # save image to param "img" # If an image has an EXIF Orientation tag, return a new image that is transposed accordingly. # Otherwise, return a copy of the image. img = ImageOps.exif_transpose(img) # tiles must be square, so get the largest square that fits inside the image w = img.size[0] h = img.size[1] min_dimension = min(w, h) w_crop = (w - min_dimension) / 2 h_crop = (h - min_dimension) / 2 img = img.crop((w_crop, h_crop, w - w_crop, h - h_crop)) large_tile_img = img.resize((TILE_SIZE, TILE_SIZE), Image.ANTIALIAS) small_tile_img = img.resize((int(TILE_SIZE / TILE_BLOCK_SIZE), int(TILE_SIZE / TILE_BLOCK_SIZE)), Image.ANTIALIAS) return large_tile_img.convert('RGB'), small_tile_img.convert('RGB') except: return None, None
def resize_image(image, size): # before we calc thumbnail, we need to check and apply EXIF-orientation image = ImageOps.exif_transpose(image) new_size, crop = get_sizes(size, image.size) image = image.resize(new_size, resample=LANCZOS) if crop: image = image.crop(crop) min_width, min_height = get_minsize(size) if min_width > new_size[0] or min_height > new_size[1]: padding = math.ceil(max(min_width - new_size[0], min_height - new_size[1]) / 2) if image.mode not in ("RGB", "RGBA"): image = image.convert('RGB') image = ImageOps.expand(image, border=padding, fill="white") new_width = max(min_width, new_size[0]) new_height = max(min_height, new_size[1]) new_x = (image.width - new_width) // 2 new_y = (image.height - new_height) // 2 image = image.crop((new_x, new_y, new_x + new_width, new_y + new_height)) return image
def handle_image_file(file): # 檢查content_type if file.content_type not in ['image/jpeg', 'image/png']: raise Exception(f'檔案不符({file.content_type})') # 檢查檔案大小 max_size = 10 * 1024 * 1024 # 10MB if file.size > max_size: raise Exception(f'檔案太大({file.size})') # 讀圖片 img = Image.open(BytesIO(file.read())) img = img.convert('RGB') # 轉成RGB(JPG只有RGB)(PNG會有RGBA) img = ImageOps.exif_transpose(img) # 解決圖片內建旋轉問題 # 等比例縮放圖片尺寸 (width, height) = img.size while width > 1024.0 or height > 1024.0: width *= 0.9 height *= 0.9 img = img.resize((int(width), int(height))) # save output_io = BytesIO() img.save(output_io, 'JPEG', quality=70) new_file = File(output_io, 'uploaded.jpg') # 避免上傳S3時錯誤 # https://stackoverflow.com/questions/51468132/baddigest-when-calling-the-putobject-operation-s3-boto new_file.seek(0) return new_file
def save(self, *args, **kwargs): super().save(*args, **kwargs) mime = magic.Magic(mime=True) oldpath = self.file.name full_tmp_path = os.path.join(settings.MEDIA_ROOT, self.file.path) if mime.from_file(full_tmp_path).split('/')[0] == "image": image = Image.open(self.file.path) image = ImageOps.exif_transpose(image) w, h = image.size resize = 640 if w > resize or h > resize: if w >= h: h = int(h / w * resize) w = resize else: w = int(w / h * resize) h = resize image = image.resize((w, h), Image.ANTIALIAS) image.save(self.file.path) else: param = ' -strict -2 -vf format=yuv420p -vf scale=-2:480 -c:v libx264 -c:a aac -b:a 128k -movflags +faststart -f mp4 ' subprocess.call('ffmpeg -i ' + self.file.path + param + self.file.path + '.mp4 -y', shell=True) if os.path.exists(self.file.path + '.mp4'): default_storage.delete(self.file.path) self.file = oldpath + '.mp4' super().save()
def upldpic(): """ Form submit and monitoring for uploading a point pic. """ # flask.request.method always returns "GET", so check for file input. picfile = flask.request.files.get("picfilein") if not picfile: logging.info("upldpic ready for upload") return util.respond("Ready", mimetype="text/plain") try: appuser, _ = util.authenticate() ptid = dbacc.reqarg("ptid", "dbid", required=True) pt = dbacc.cfbk("Point", "dsId", ptid, required=True) logging.info(appuser["email"] + " upldpic Point " + str(ptid)) if not appuser["dsId"] in util.csv_to_list(pt["editors"]): raise ValueError("Not authorized to edit this point") img = Image.open(picfile) img = ImageOps.exif_transpose(img) # correct vertical orientation sizemaxdims = 400, 400 # max allowed width/height for thumbnail resize img.thumbnail(sizemaxdims) # modify, preserving aspect ratio bbuf = io.BytesIO() # file-like object for save img.save(bbuf, format="PNG") pt["pic"] = base64.b64encode(bbuf.getvalue()) pt = dbacc.write_entity(pt, pt["modified"]) except ValueError as e: logging.info("upldpic Point " + str(ptid) + ": " + str(e)) return util.serve_value_error(e) return util.respond("Done: " + pt["modified"], mimetype="text/plain")
def resize_emoji(image_data: bytes, size: int = DEFAULT_EMOJI_SIZE) -> bytes: try: im = Image.open(io.BytesIO(image_data)) image_format = im.format if image_format == "GIF": assert isinstance(im, GifImageFile) # There are a number of bugs in Pillow.GifImagePlugin which cause # results in resized gifs being broken. To work around this we # only resize under certain conditions to minimize the chance of # creating ugly gifs. should_resize = ( im.size[0] != im.size[1] # not square or im.size[0] > MAX_EMOJI_GIF_SIZE # dimensions too large or len(image_data) > MAX_EMOJI_GIF_FILE_SIZE_BYTES # filesize too large ) return resize_gif(im, size) if should_resize else image_data else: im = ImageOps.exif_transpose(im) im = ImageOps.fit(im, (size, size), Image.ANTIALIAS) out = io.BytesIO() im.save(out, format=image_format) return out.getvalue() except OSError: raise BadImageError( _("Could not decode image; did you upload an image file?")) except DecompressionBombError: raise BadImageError(_("Image size exceeds limit."))
def compress_picture(picture, compressed_size): try: im = Image.open(picture) except IOError: logger.error('An invalid image was submitted') return None logger.info('Compressing picture, target size %sx%s' % (compressed_size[0], compressed_size[1])) # get correct orientation # PIL has an error, skip operation if error arises try: im = ImageOps.exif_transpose(im) except TypeError: logger.error('PIL error %s - image rotated manually' % str(picture)) im = im.rotate(270, expand=True) except IndexError: logger.error('PIL IndexError - {image} not rotated. May need to check it manually'.format(image=str(picture))) im = im.rotate(180, expand=True) output = BytesIO() im.thumbnail(compressed_size) im.save(output, format='JPEG', quality=90) output.seek(0) picture = InMemoryUploadedFile(output, 'PictureField', "%s.jpg" % picture.name.split('.')[0], 'image/jpeg', sys.getsizeof(output), None) size = sys.getsizeof(output) / 1000000 logger.info('Picture compressed to %s Mb\n' % size) return picture
def gen_batches(files, scale_bs=10, aug_bs=5, crop_size=600, scale=4): from imgaug.augmentables.batches import UnnormalizedBatch skip = 0 for xml_file in files: tree = ET.parse(xml_file) root = tree.getroot() img = root.find('path').text try: raw_img = Image.open(img) clean(raw_img) raw_img = ImageOps.exif_transpose(raw_img) # resize_image(raw_img, root, scale) # img_array = np.array(raw_img) img_array = resize_fix_shape(raw_img, root, crop_size) images = [img_array for _ in range(scale_bs)] bbs = [ ia.BoundingBox(int(member[4][0].text), int(member[4][1].text), int(member[4][2].text), int(member[4][3].text)) for member in root.findall('object') ] images_scale, bbs_scale = seq_scale( images=images, bounding_boxes=[bbs for _ in range(scale_bs)]) imgs = [im for im in images_scale for _ in range(aug_bs)] batche = UnnormalizedBatch(images=imgs, bounding_boxes=[ bbss for bbss in bbs_scale for _ in range(aug_bs) ]) except Exception as e: skip += 1 print(repr(e), f" skip {skip}") yield batche
def save(self): im = Image.open(self.photo) im = ImageOps.exif_transpose(im) im = im.convert('RGB') if im.width > 2000 and im.height > 2000: print('big picturee') output = BytesIO() half = 0.5 im = im.resize([int(half * s) for s in im.size]) # im = im.resize( (1000,1000) ) im.save(output, format='JPEG', quality=50) output.seek(0) self.photo = InMemoryUploadedFile( output, 'ImageField', "%s.jpg" % self.photo.name.split('.')[0], 'image/jpeg', sys.getsizeof(output), None) super(BlogPost, self).save() else: output = BytesIO() im.save(output, format='JPEG', quality=30) output.seek(0) self.photo = InMemoryUploadedFile( output, 'ImageField', "%s.jpg" % self.photo.name.split('.')[0], 'image/jpeg', sys.getsizeof(output), None) super(BlogPost, self).save()
def convert(source, date): """Converts all input images to a max size of 640x640 pixels and copies into a folder called 'images'. Args: source (str): Source of the images date (str): Destination folder """ print("----------") print("Converting all images to JPG format for processing") print("----------") counter = 1 for pic in tqdm(os.listdir(source)): try: im = Image.open(source + pic) im.thumbnail(size=(640, 640)) im = ImageOps.exif_transpose(im) im = im.convert('RGB') im.save(f"{source}/{date}_image_{counter:04}.jpg") os.remove(source + pic) counter += 1 except: pass
def save_thumbnail(imagename, imagedirectory, thumb_dir): """Save a thumbnail for this image""" create_image_directory(thumb_dir) image = ImageOps.exif_transpose(Image.open(join(imagedirectory, imagename))) image.thumbnail((THUMBNAILWIDTH, THUMBNAILHEIGHT)) image.save(join(thumb_dir, imagename))
def pillow2array(img, flag='color'): # Handle exif orientation tag if flag in ['color', 'grayscale']: img = ImageOps.exif_transpose(img) # If the image mode is not 'RGB', convert it to 'RGB' first. if img.mode != 'RGB': if img.mode != 'LA': # Most formats except 'LA' can be directly converted to RGB img = img.convert('RGB') else: # When the mode is 'LA', the default conversion will fill in # the canvas with black, which sometimes shadows black objects # in the foreground. # # Therefore, a random color (124, 117, 104) is used for canvas img_rgba = img.convert('RGBA') img = Image.new('RGB', img_rgba.size, (124, 117, 104)) img.paste(img_rgba, mask=img_rgba.split()[3]) # 3 is alpha if flag in ['color', 'color_ignore_orientation']: array = np.array(img) elif flag in ['grayscale', 'grayscale_ignore_orientation']: img = img.convert('L') array = np.array(img) else: raise ValueError( 'flag must be "color", "grayscale", "unchanged", ' f'"color_ignore_orientation" or "grayscale_ignore_orientation"' f' but got {flag}') return array
def getImage(self): imageBytes = self.imageBytes nome_da_imagem = self.nome_da_imagem im = PILImage.open(imageBytes) im = ImageOps.exif_transpose(im) newsizex = int(float(self.newsizex)) newsizey = int(float(self.newsizey)) cuttersizex = int(float(self.cuttersizex)) cuttersizey = int(float(self.cuttersizey)) positionx = float(self.positionx) positiony = float(self.positiony) nome_do_arquivo, extensao = os.path.splitext(nome_da_imagem) im = im.crop( (positionx, positiony, positionx + newsizex, positiony + newsizey)) im = im.resize((cuttersizex, cuttersizey), PILImage.ANTIALIAS) jpeg_image_buffer = io.BytesIO() if extensao.lower() == '.png' or self.force_png: self.extensao = 'png' self.nome_da_imagem = "%s.%s" % (nome_do_arquivo, "png") im.save(jpeg_image_buffer, 'png') else: self.extensao = 'jpg' self.nome_da_imagem = "%s.%s" % (nome_do_arquivo, "jpg") im.save(jpeg_image_buffer, format='JPEG', quality=100) jpeg_image_buffer.seek(0) data = jpeg_image_buffer.read() return data
def updateAPI (currImage, c, UID): fileName = currImage.split("/")[-1] picture = Image.open(currImage) picture = ImageOps.exif_transpose(picture) rgb_picture = picture.convert('RGB') rgb_picture.save(BASE_DIR +"/min/" +fileName + ".jpg", "JPEG", optimize = True, quality = 40) finalLink = "https://i.rotorhead.club/min/" + fileName + ".jpg" c.execute('UPDATE images SET minImg = ? WHERE UID = ?', (finalLink, UID)) c.execute('SELECT * FROM images') data = c.fetchall() #print(type(data)) finalDict = {} for i in range(len(data)): finalDict[data[i][0]] = {'UID': data[i][1], 'Desc' : data[i][2], "Link": data[i][3], "GID" : data[i][4], "minLink" : data[i][5]} with open(file_path, 'w') as jsonFile: json.dump(finalDict, jsonFile, indent=4, sort_keys=True) return True
def find_email(): global _dt_sender global _dt global _dt_date global _dp global _num_emails # get most recent email files = [f for f in listdir(_sender_dir) if isfile(join(_sender_dir, f))] files.sort() _num_emails = len(files) try: filename = files[_selected_email] except: logging.info('find email called too soon') return try: fh = open(join(_sender_dir, filename), 'r') _dt_sender = fh.read().rstrip('\n') fh.close() except: logging.error('Failed to open {}'.format(join(_sender_dir, filename))) logging.info('uid: {}'.format(filename)) logging.info('_dt_sender: {}'.format(_dt_sender)) try: fh = open(join(_text_dir, filename), 'r') _dt = fh.read().rstrip('\n') fh.close() except: logging.error('Failed to open {}'.format(join(_text_dir, filename))) logging.info('_dt: {}'.format(_dt)) try: fh = open(join(_date_dir, filename), 'r') file_date = fh.read().rstrip('\n') fh.close() except: logging.error('Failed to open {}'.format(join(_date_dir, filename))) _dt_date = datetime.strptime( file_date, '%a, %d %b %Y %H:%M:%S %z').strftime('%m/%d/%y %l%p') logging.info('_dt_date: {}'.format(_dt_date)) try: im1 = Image.open(join(_photo_dir, filename)) except: logging.error('Failed to open {}'.format(join(_photo_dir, filename))) try: im1 = ImageOps.exif_transpose(im1) extra_width = im1.width - _app_width _dp = im1.crop((extra_width / 2, 0, _app_width + (extra_width / 2), _app_height + 20)) except: logging.error('Failed to crop {}'.format(filename))
def __process_tile(self, tile_path): try: # open file path img = Image.open(tile_path) # if an image has an EXIF Orientation tag, return a new image that is transposed accordingly. img = ImageOps.exif_transpose(img) # tiles must be square, so get the largest square that fits inside the image w = img.size[0] h = img.size[1] # get the min of (height, width) return the min values to crop following the min. min_dims = min(w, h) # ex: 400x600 image. min = 400. w_c = 0, h_c = 100. --> crop height. w_crop = (w - min_dims) / 2 h_crop = (h - min_dims) / 2 # ex: img.crop((0, 100, 400, 500)) ----> img.crop(left, upper, right, lower) img = img.crop((w_crop, h_crop, w - w_crop, h - h_crop)) # After crop, the images now is square and balance in with and height (w=h). # resize((width, height)) large_tile_img = img.resize((SUB_IMAGE_SIZE, SUB_IMAGE_SIZE), Image.ANTIALIAS) small_tile_img = img.resize( (int(SUB_IMAGE_SIZE / TILE_BLOCK_SIZE), int(SUB_IMAGE_SIZE / TILE_BLOCK_SIZE)), Image.ANTIALIAS) # We have Large title and small title on the same target. return large_tile_img.convert('RGB'), small_tile_img.convert('RGB') except: return None, None
def _save_file(self, file: TextIO) -> str: # save image with Image.open(file) as im: # set filename ext = im.format.lower() filename = uuid.uuid4().hex + '.' + ext if self.square: # crop to center and resizes to the dimensions you specify img = self._crop_max_square(im).resize( (self.width, self.height), Image.LANCZOS) else: # resizes to the largest size img img = self._resize_thumbnail(im, self.width, self.height) # remove exif tag img = self._remove_exif_tag(img) # flip image to right path img = ImageOps.exif_transpose(img) # if watermark exists set watermark if hasattr(self, 'watermark'): img = self._set_watermark(img) if hasattr(self, 'dir_name'): # create directory if file isn't exists path = os.path.join(self._BASE_DIR, self.path_upload, self.dir_name) if not os.path.exists(path): os.mkdir(path) img.save(os.path.join(path, filename)) else: img.save( os.path.join(self._BASE_DIR, self.path_upload, filename)) return filename
def create_thumbnail(sourcename, size): source = default_storage.open(sourcename) image = Image.open(BytesIO(source.read())) try: image.load() except: raise ThumbnailError('Could not load image') # before we calc thumbnail, we need to check and apply EXIF-orientation image = ImageOps.exif_transpose(image) scale, crop = get_sizes(size, image.size) image = image.resize(scale, resample=LANCZOS) if crop: image = image.crop(crop) checksum = hashlib.md5(image.tobytes()).hexdigest() name = checksum + '.' + size.replace('^', 'c') + '.png' buffer = BytesIO() if image.mode not in ("1", "L", "RGB", "RGBA"): image = image.convert('RGB') image.save(fp=buffer, format='PNG') imgfile = ContentFile(buffer.getvalue()) t = Thumbnail.objects.create(source=sourcename, size=size) t.thumb.save(name, imgfile) return t
def pre_save(self, model_instance, add): """Prepares the image for saving by scaling it to the desired dimensions.""" file = getattr(model_instance, self.attname) if file and not file._committed: # Open the image with Pillow and save the original format attribute im = Image.open(file.file) im_format = im.format # If the image contains exif rotation data, rotate it accordingly im = ImageOps.exif_transpose(im) # Rescale the image, if necessary im.thumbnail((self.max_width, self.max_height), resample=Image.LANCZOS) # Save it to an in-memory file temp = io.BytesIO() im.save(temp, format=im_format, quality=75) # Hash the contents for a filename filename = f"{hashlib.md5(temp.getvalue()).hexdigest()}.{im_format}" # Create a new InMemoryUploadedFile new_file = InMemoryUploadedFile( temp, self.name, filename, f'image/{im_format.lower()}', sys.getsizeof(temp), None ) # Reassign the `file` and `name` attributes file.file = new_file file.name = filename # Save the file file.save(file.name, file.file, save=False) return file