예제 #1
0
    def _convert_image(self, file_path: str, preview_dims: ImgDims) -> Image:
        """
        refer: https://legacy.imagemagick.org/Usage/thumbnails/
        like cmd: convert -layers merge  -background white -thumbnail widthxheight \
        -auto-orient -quality 85 -interlace plane input.jpeg output.jpeg
        """

        img = Image(filename=file_path)
        resize_dim = compute_resize_dims(dims_in=ImgDims(width=img.width,
                                                         height=img.height),
                                         dims_out=preview_dims)

        img.auto_orient()
        img.iterator_reset()
        img.background_color = Color("white")
        img.merge_layers("merge")

        if self.progressive:
            img.interlace_scheme = "plane"

        img.compression_quality = self.quality

        img.thumbnail(resize_dim.width, resize_dim.height)

        return img
예제 #2
0
def orient_and_resize(image_filename):
    resized_images = {}
    
    img = Image(filename=image_filename)
    img.auto_orient()

    (w,h) = img.size
    w = int(w)
    h = int(h)

    filename_base = image_filename
    filename_base = filename_base.replace("/", "-")
    filename_base = filename_base.replace(" ", "_")

    with img.clone() as img_clone:
        img_clone.resize(1280, int((1280.0/w)*h))
        fname = "Resized/" + filename_base + "_1280.jpg"
        resized_images['1280'] = fname
        img_clone.save(filename=PREFIX_DIR + fname)

    with img.clone() as img_clone:
        img_clone.resize(640, int((640.0/w)*h))
        fname = "Resized/" + filename_base + "_640.jpg"
        resized_images['640'] = fname
        img_clone.save(filename=PREFIX_DIR + fname)

    with img.clone() as img_clone:
        img_clone.resize(320, int((320.0/w)*h))
        fname = "Resized/" + filename_base + "_320.jpg"
        resized_images['320'] = fname
        img_clone.save(filename=PREFIX_DIR + fname)

    with img.clone() as img_clone:
        img_clone.resize(160, int((160.0/w)*h))
        fname = "Resized/" + filename_base + "_160.jpg"
        resized_images['160'] = fname
        img_clone.save(filename=PREFIX_DIR + fname)

    img.close()
    return ((w, h), resized_images)
예제 #3
0
def resize_image(path=None, blob=None, img=None, name=None,
                 fmt='jpeg', auto_orient=True, upscale=False):
    """A coroutine that resizes a single image multiple times

    Note that the same image buffer is used across multiple operations so
    operations should be ordered from highest-quality to lowest.

    Parameters:
     - path/blob/img: Source data  (img is a Wand Image object)
     - name: The name of the file (for logging purposes only)
     - fmt: The image format of the resulting images (default: 'jpeg')
     - auto_orient: Automatically orient image before processing (default: true)
     - upscale: Upscale images to fit the desired resolution if they're too small
                (default: False)

    Receives a 4-tuple of (size, quality, square, fp)
     - size: The image will be resized so that the longest edge is this many pixels.
             If None the image will not be resized.
     - quality: The JPEG quality level
     - square: If true, the images will be cropped to square before being resized
     - fp: A file-like object to write() the result into
    """
    if sum([bool(path), bool(blob), bool(img)]) != 1:
        raise ValueError("One of 'path', 'blob', or 'img' is required")
    if path:
        img = Image(filename=path)
    elif blob:
        img = Image(blob=blob)

    with img:
        # If there are multiple frames only use the first one (this
        # prevents GIFs and ICOs from exploding their frames into
        # individual images)
        if img.sequence:
            for _ in range(1, len(img.sequence)):
                img.sequence.pop()

        # Rotation and conversion to desired output format
        if auto_orient:
            img.auto_orient()
        img.format = fmt

        while True:
            size, quality, square, fp = yield

            __log__.debug("[resizing] %s -> %s%s",
                name or "<img data>",
                "{}px".format(size) if size else "fullsize",
                ", square" if square else ""
            )

            if square:
                crop = min(img.size)
                img.crop(width=crop, height=crop, gravity='center')
                if size is not None and (upscale or size < crop):
                    img.resize(size, size)
            elif size is not None:
                # Work around a bug in Wand's image transformation by
                # manually calculating the scaled dimensions and resizing
                ratio = size/max(img.size)
                if upscale or ratio < 1:
                    img.resize(*[round(x*ratio) for x in img.size])

            img.compression_quality = quality

            try:
                img.save(file=fp)
            except IOError as e:
                __log__.error("[error] Failed to write image: %s", e, exc_info=True)
                raise