Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
 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}"
Ejemplo n.º 5
0
 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
Ejemplo n.º 6
0
    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
Ejemplo n.º 7
0
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"))
Ejemplo n.º 8
0
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()
Ejemplo n.º 9
0
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."))
Ejemplo n.º 10
0
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]
Ejemplo n.º 11
0
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")
Ejemplo n.º 12
0
    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
Ejemplo n.º 13
0
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
Ejemplo n.º 14
0
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
Ejemplo n.º 15
0
    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()
Ejemplo n.º 16
0
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")
Ejemplo n.º 17
0
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."))
Ejemplo n.º 18
0
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
Ejemplo n.º 19
0
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
Ejemplo n.º 20
0
    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()
Ejemplo n.º 21
0
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
Ejemplo n.º 22
0
Archivo: utils.py Proyecto: Uninett/nav
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))
Ejemplo n.º 23
0
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
Ejemplo n.º 24
0
 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
Ejemplo n.º 25
0
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
Ejemplo n.º 26
0
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))
Ejemplo n.º 27
0
    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
Ejemplo n.º 29
0
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
Ejemplo n.º 30
0
    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