Example #1
0
def crop_row(image_to_crop: Image, original_image: Image) -> (Image, Image):
    transposed_image_to_crop = image_to_crop.rotate(90, expand=True)
    transposed_original_image = original_image.rotate(90, expand=True)
    cropped_image, marked_original_image = crop_column(
        transposed_image_to_crop, transposed_original_image)
    return (cropped_image.rotate(3 * 90, expand=True),
            marked_original_image.rotate(3 * 90, expand=True))
Example #2
0
def _check_rotation_exif(image: Image) -> Image:
    """
    Checks the rotational exif data on a given image and rotates it
    accordingly.
    :param image:
    :return:
        Rotated image.
    :rtype:
        PIL.Image
    """
    for orientation in ExifTags.TAGS.keys():
        if ExifTags.TAGS[orientation] == 'Orientation':
            try:
                exif = dict(image._getexif().items())
                val = exif[orientation]
            except (AttributeError, KeyError):
                return image

            if val == 3:
                image = image.rotate(180, expand=True)
            elif val == 6:
                image = image.rotate(270, expand=True)
            elif val == 8:
                image = image.rotate(90, expand=True)
            return image
    return image
Example #3
0
def rotate_within_exif(img: Image):
    orientation = img.getexif().get(ORIENTATION_EXIF_TAG,
                                    ORIENTATION.NORMAL_HORIZONTAL)
    if orientation in [
            ORIENTATION.NORMAL_180_ROTATED, ORIENTATION.MIRROR_VERTICAL
    ]:
        img = img.rotate(180, expand=True)
    elif orientation in [
            ORIENTATION.NORMAL_270_ROTATED,
            ORIENTATION.MIRROR_HORIZONTAL_90_ROTATED
    ]:
        img = img.rotate(90, expand=True)
    elif orientation in [
            ORIENTATION.NORMAL_90_ROTATED,
            ORIENTATION.MIRROR_HORIZONTAL_270_ROTATED
    ]:
        img = img.rotate(270, expand=True)
    if orientation in [
            ORIENTATION.MIRROR_HORIZONTAL,
            ORIENTATION.MIRROR_VERTICAL,
            ORIENTATION.MIRROR_HORIZONTAL_270_ROTATED,
            ORIENTATION.MIRROR_HORIZONTAL_90_ROTATED,
    ]:
        img = img.transpose(Image.FLIP_LEFT_RIGHT)
    return img
Example #4
0
 def transform_rotate(img: Image, labels: Image, deg: Optional[float] = None):
     if deg is None:
         deg = np.random.rand() * 5.
     img = img.rotate(deg)
     labels = labels.rotate(deg)
     # TODO: smarter crop then margin = angle...
     img, labels = Loader.transform_crop(img, labels, margin=deg / 100)
     return img, labels
Example #5
0
def rotate_image_to_direction(image: Image, direction: Direction) -> Image:
    if direction == Direction.RIGHT:
        return image
    elif direction == Direction.UP:
        return image.rotate(90)
    elif direction == Direction.LEFT:
        return image.transpose(Image.FLIP_LEFT_RIGHT)
    elif direction == Direction.DOWN:
        return image.rotate(90*3)

    raise ValueError("Invalid direction")
Example #6
0
def exif_rotate(image: Image) -> Image:
    if hasattr(image, '_getexif') is False:
        return image
    exif_dict = dict(image._getexif().items())
    orientation = exif_dict.get(name_to_tag_num['Orientation'])

    if orientation == 3:
        return image.rotate(180, expand=True)
    elif orientation == 6:
        return image.rotate(270, expand=True)
    elif orientation == 8:
        return image.rotate(90, expand=True)

    return image
Example #7
0
    def _assert_expected_chained(self, case):
        with open(case["source_path"], "rb") as f:
            img = Image(f)
            for operation in case["operation"]:
                if operation == "resize":
                    img.resize(case["width"], case["height"])
                elif operation == "rotate":
                    img.rotate(case["degree"])
                elif operation == "region":
                    img.region(case["rect"].split(","))
            rv = img.save()

            with open(case["expected_path"], "rb") as expected:
                msg = "{} does not match {}".format(case["source_path"], case["expected_path"])
                self.assertEqual(rv.read(), expected.read(), msg)
def clip_and_align(img: Image) -> Image:
    try:
        # 识别关键点
        landmarks = face_recognition.face_landmarks(np.array(img), model='small')[0]
        print(landmarks)
        l_eye = landmarks['left_eye']
        r_eye = landmarks['right_eye']
        l_mean = np.mean(l_eye, axis=0).astype(int)
        r_mean = np.mean(r_eye, axis=0).astype(int)
        dy = r_mean[1] - l_mean[1]
        dx = r_mean[0] - l_mean[0]
        # 计算旋转角度
        angle = math.atan2(dy, dx) * 180. / math.pi
        # 旋转
        img = img.rotate(angle, expand=True)
        # 再次识别
        landmarks = face_recognition.face_landmarks(np.array(img), model='small')[0]
        # 剪裁, 以鼻子为中心
        nose = landmarks['nose_tip']
        center = np.mean(nose, axis=0).astype(int)
        center[0] = max(center[0], clip_size // 2)
        center[0] = min(center[0], img.size[0] - clip_size // 2)
        center[1] = max(center[1], clip_size // 2)
        center[1] = min(center[1], img.size[1] - clip_size // 2)
        assert clip_size % 2 == 0
        left = center[0] - clip_size // 2
        right = center[0] + clip_size // 2
        down = center[1] + clip_size // 2
        top = center[1] - clip_size // 2
        img = img.crop((left, top, right, down))
        assert img.size == (clip_size, clip_size)
        return img
    except:
        # 部分图片过于模糊,排除
        return None
    def preprocess_im(im: Image,
                      height_offset: int = 100,
                      rotation: int = 180,
                      brightness_factor: float = None) -> Image:
        """
        Method preprocessing an image

        Parameters
        ----------
        im : Image
            Image to be preprocessed
        height_offset : int, optional
            `height_offset` will be cropped from the top of the image. This transformation is applied before `rotation`.
            By default, pikrellcam prints the date and time in its video. Thus, by default 100
        rotation : int, optional
            Rotate the image by `rotation` degrees. On my rpi, the camera is upside down, thus, by default 180
        brightness_factor : float, optional
            Factor by which to scale the brightness by. 2.5 is a good number for a brighter image. If None, leave the
            brightness unadjusted, by default None.

        Returns
        -------
        Image
            Image preprocessed
        """
        w, h = im.size

        im = im.crop((0, height_offset, w, h))
        im = im.rotate(rotation)

        if brightness_factor is not None:
            enhancer = ImageEnhance.Brightness(im)
            im = enhancer.enhance(brightness_factor)

        return im
    def insert_cropped_face(self, face_image: Image, empty_face_idx=0):
        if len(self.empty_faces) == 0 or empty_face_idx > len(
                self.empty_faces):
            raise "No faces or face index is out of bounds"

        if self.img is None:
            raise "Main splash image is not set"

        face_bounds = self.empty_faces[empty_face_idx]
        face_box = (face_bounds.left, face_bounds.top,
                    face_bounds.left + face_bounds.width,
                    face_bounds.top + face_bounds.height)

        logger.info(
            "Face Bounds: {0}  Image Size: {1} Face Image Size: {2}".format(
                str(face_bounds), self.img.size, face_image.size))
        cropped_face_image = Image.new("RGBA", self.img.size)

        #Would like to use thumbnail, but for some reason throws an error for images not matching in pillow when pasting below
        #face_image.thumbnail((face_bounds.width, face_bounds.height), Image.ANTIALIAS)
        face_image = face_image.resize((face_bounds.width, face_bounds.height),
                                       Image.ANTIALIAS)

        if face_bounds.angle > 0:
            logger.info("Angling")
            face_image = face_image.rotate(face_bounds.angle)
            logger.info("New face image size: {0}".format(face_image.size))

        cropped_face_image.paste(face_image, face_box)
        self.empty_face_layers.append(cropped_face_image)
Example #11
0
 def rotate(im: Image) -> Image:
     """
     Rotates an pillow.Image image
     :param im: the image
     :return: rotated pillow.Image object
     """
     return im.rotate(random.randint(0, 360))
Example #12
0
def drawLine(im: Image, canvas: Image, point: tuple, theta: int, scale=1.0):
    # im: assumed to be a line; width ignored
    # theta: int deg, within [-90, 90]
    # positive is counter-clockwise (to the right)
    im_rotated = im.rotate(theta, expand=True, resample=Image.BICUBIC)
    # im_enhanced = im_rotated.filter(ImageFilter.SMOOTH)
    im_scaled = im_rotated.resize(
        (round(im_rotated.size[0] * scale), round(im_rotated.size[1] * scale)))
    h = im.size[1] * scale
    x, y = point
    theta = mathutils.normalize_into_interval(theta, (-180, 180))
    if 0 <= theta <= 90:
        top_left = point
    elif 90 < theta <= 180:
        top_left = (x, round(y - h * cos(theta)))
    elif -90 <= theta < 0:
        top_left = (round(x - h * sin(theta)), y)
    elif -180 <= theta < -90:
        top_left = (round(x - h * sin(theta)), round(y - h * cos(theta)))

    paste(im_scaled, canvas, top_left)

    # returns the endpoint of the line
    return (round(x + h * math.sin(math.radians(theta))),
            round(y + h * math.cos(math.radians(theta))))
Example #13
0
    def recover_rotate(self, image: Image, angle: int):
        """
        Rotates the input image back to fit the original image, \
            and fills in the parts that are missing due to rotation.
        Assumes that the angle of rotation is provided, and that the image \
            has not been expanded when rotated (i.e. corners have been cut off).
        Also ssumes that no other modification has been made to the input.

        :param image: input image
        :type image: PIL.Image
        :param angle: the degree that the image was rotated (CCW)
        :type angle: int

        :return: the input image modified to match the original image
        :rtype: PIL.Image
        """
        out = image.rotate(-angle)
        '''
        for coord in product(range(self.original.size[1]), range(self.original.size[0])):
            if out.getpixel(coord) != 0:
                out.putpixel(coord, self.original.getpixel(coord))
        '''
        #mask = out.convert(mode="1",dither=None).convert('L')  # insufficient masking
        mask = out.point(lambda x: 255*int(x>0))
        mask = invert(mask).convert('1')
        out.paste(self.original,mask=mask)

        return out
Example #14
0
def rotate_by_orient(img: Image) -> Image:
    """
    Rotate image by exif orientation tag
    :param img: original image
    :return: rotated image
    """
    orientation = 0x0112

    exif = dict(img.getexif())
    if orientation in exif:
        if exif[orientation] == 3:
            img = img.rotate(180, expand=True)
        elif exif[orientation] == 6:
            img = img.rotate(270, expand=True)
        elif exif[orientation] == 8:
            img = img.rotate(90, expand=True)
    return img
Example #15
0
def rotate_image(im: Image) -> Image:
    try:
        orientation = -1
        for orientation in ExifTags.TAGS.keys():
            if ExifTags.TAGS[orientation] == 'Orientation': break
        exif = dict(im._getexif().items())

        if orientation in exif and exif[orientation] == 3:
            im = im.rotate(180, expand=True)
        elif orientation in exif and exif[orientation] == 6:
            im = im.rotate(270, expand=True)
        elif orientation in exif and exif[orientation] == 8:
            im = im.rotate(90, expand=True)
    except Exception as ex:
        logging.debug(ex)

    return im
Example #16
0
def exif_rotate(image: Image) -> Image:
    if not hasattr(image, "_getexif"):
        return image
    exif_data = image._getexif()
    if exif_data is None:
        return image

    exif_dict = dict(exif_data.items())
    orientation = exif_dict.get(name_to_tag_num["Orientation"])

    if orientation == 3:
        return image.rotate(180, expand=True)
    elif orientation == 6:
        return image.rotate(270, expand=True)
    elif orientation == 8:
        return image.rotate(90, expand=True)

    return image
Example #17
0
def exif_rotate(image: Image) -> Image:
    if not hasattr(image, '_getexif'):
        return image
    exif_data = image._getexif()
    if exif_data is None:
        return image

    exif_dict = dict(exif_data.items())
    orientation = exif_dict.get(name_to_tag_num['Orientation'])

    if orientation == 3:
        return image.rotate(180, expand=True)
    elif orientation == 6:
        return image.rotate(270, expand=True)
    elif orientation == 8:
        return image.rotate(90, expand=True)

    return image
Example #18
0
def exif_rotate(image: Image) -> Image:
    if not hasattr(image, '_getexif'):
        return image
    exif_data = image._getexif()
    if exif_data is None:  # nocoverage # don't have a test image for this case, but it happens
        return image

    exif_dict = dict(exif_data.items())
    orientation = exif_dict.get(name_to_tag_num['Orientation'])

    if orientation == 3:
        return image.rotate(180, expand=True)
    elif orientation == 6:
        return image.rotate(270, expand=True)
    elif orientation == 8:
        return image.rotate(90, expand=True)

    return image
 def __call__(self, im: Image) -> Image:
     """
     Produces a randomly rotated image every time the instance is called.
     Args:
         im: The image to rotate.
     Returns:    
         Randomly rotated image.
     """
     return im.rotate(angle=random.sample(population=self.degrees, k=1)[0])
Example #20
0
def random_Rotation(image):
    """
     对图像进行随机任意角度(0~360度)旋转
    :param mode 邻近插值,双线性插值,双三次B样条插值(default)
    :param image PIL的图像image
    :return: 旋转转之后的图像
    """
    random_angle = np.random.randint(1, 360)
    image = Image.rotate(random_angle)
    return image
Example #21
0
def rotate(image: Image, angle: int):
    """
    :param image: input image
    :type image: PIL.Image
    :param angle: the degrees by which to rotate the input image (CCW)
    :type angle: int 

    :return: the modified image
    :rtype: PIL.Image
    """
    return image.rotate(angle)
Example #22
0
def rotate_image(image: Image) -> Image:
    ALLOCATION={3: 180,
                6: -90,
                8: 90}        #{orientation value : rotation angle}
    exif=image._getexif()
    # print(f"exif={exif}")
    if exif != None and 274 in exif:
        if exif[274] in ALLOCATION:
            return image.rotate(ALLOCATION[exif[274]], expand=True)
        else: return image
    else: return image
Example #23
0
    def rotate_upright(self, image: Image):
        """
        Rotate a PIL image to upright depending on its current orientation according to EXIF data.
        """
        try:
            for orientation in ExifTags.TAGS.keys():
                if ExifTags.TAGS[orientation] == "Orientation":
                    break
            exif = dict(image._getexif().items())

            orientation = exif[orientation]
            if orientation == 3:
                image = image.rotate(180, expand=True)
            elif orientation == 6:
                image = image.rotate(270, expand=True)
            elif orientation == 8:
                image = image.rotate(90, expand=True)
        except (AttributeError, KeyError) as e:
            pass
        return image
Example #24
0
 def simple_geometry_transform(self, image: Image, size: Tuple(int, int), angle: int) -> Tuple[object, bool]:
     '''
     resize and rotate something
     '''
     status = True
     try:
         image = image.resize(size)
         image = image.rotate(angle)  # degrees counter-clockwise
     except:
         status = False
     return (image, status)
Example #25
0
 def _renderCrewmate(image_path: str, crewmate: Image, index: int, total: int):
     fly_over_speed = 1.8 # 2 is half of the screen width
     degree = index * 360 / total * -1
     image = Image.open(image_path)
     c_w, c_h = crewmate.size
     crewmate_rotated = crewmate.rotate(degree, expand=True)
     sky_w, sky_h = image.size
     x_offset = -1 * c_w + index * sky_w // total * fly_over_speed
     offset = (int(x_offset), (sky_h - c_h) // 2)
     image.paste(crewmate_rotated, offset)
     return image
Example #26
0
def apply_transformations(image: Image, params: Params):
    image_width, image_height = image.size

    # If crop dimensions are set to 0 or exceed image dimensions set crop dimensions to image dimensions.
    if image_width < params.crop_width or params.crop_width == 0:
        params.crop_width = image_width
    if image_height < params.crop_height or params.crop_height == 0:
        params.crop_height = image_height

    # If size parameter is not given set size of image to the size of input image.
    if params.size is None:
        params.size["width"] = image_width
        params.size["height"] = image_height

    # Coordinates of upper left corner of crop window are random values such that image contains window.
    crop_x: int = random.randint(0, image_width - params.crop_width)
    crop_y: int = random.randint(0, image_height - params.crop_height)

    image = image.crop((crop_x, crop_y, crop_x + params.crop_width,
                        crop_y + params.crop_height))

    # Rotation degree is random value between min_rotation and max_rotation parameters.
    degrees: float = random.uniform(params.min_rotation, params.max_rotation)
    image = image.rotate(degrees)

    # Flip parameters are equal to probability of applying flip.
    if random.random() < params.flip_horizontal:
        image = image.transpose(Image.FLIP_LEFT_RIGHT)

    if random.random() < params.flip_vertical:
        image = image.transpose(Image.FLIP_TOP_BOTTOM)

    # Apply all filters. Default filter parameters result in not changing input image.
    image = image.convert("RGB")
    if params.edges:
        image = image.filter(ImageFilter.FIND_EDGES)

    enhancer = ImageEnhance.Brightness(image)
    image = enhancer.enhance(params.brightness)

    enhancer = ImageEnhance.Contrast(image)
    image = enhancer.enhance(params.contrast)

    enhancer = ImageEnhance.Sharpness(image)
    image = enhancer.enhance(params.sharpness)

    enhancer = ImageEnhance.Color(image)
    image = enhancer.enhance(params.color)

    # Return resized image to match requested output dimensions.
    return image.resize(tuple(params.size))
Example #27
0
    def auto_rotate(self, img: Image) -> Image:
        exif = img.getexif() if hasattr(img, "getexif") else None

        if not exif:
            return img

        orientation_key = 274  # cf ExifTags
        if orientation_key in exif:
            orientation = exif[orientation_key]

            rotate_values = {3: 180, 6: 270, 8: 90}

            if orientation in rotate_values:
                return img.rotate(rotate_values[orientation], expand=True)
        return img
    def _rotate_exif_orientation(self, img: Image) -> Image:
        """Rotate the image according to metadata in the payload.

        Some cameras do not rotate the image, they just add orientation
        metadata to the file, so we rotate it here.
        """
        if not hasattr(img, '_getexif'):
            return img  # PIL.PngImagePlugin.PngImageFile apparently lacks EXIF
        tags = img._getexif()
        if tags is None:
            return img
        orientation = tags.get(self.EXIF_TAGS['Orientation'])
        if orientation is None:
            return img
        degrees = self.EXIF_ROTATION_FIX.get(orientation)
        return img.rotate(degrees) if degrees else img
    def unetnested_multi_scale_predict(self, image_ori: Image):
        self.unetNested_model.eval()

        # 预测原图
        sample_ori = image_ori.copy()
        output_ori = self.unetnested_predict(sample_ori)

        # 预测旋转三个
        angle_list = [90, 180, 270]
        for angle in angle_list:
            img_rotate = image_ori.rotate(angle, Image.BILINEAR)
            output = self.unetnested_predict(img_rotate)
            pred = output.data.cpu().numpy()[0]
            pred = pred.transpose((1, 2, 0))
            m_rotate = cv2.getRotationMatrix2D((200, 200), 360.0 - angle, 1)
            pred = cv2.warpAffine(pred, m_rotate, (400, 400))
            pred = pred.transpose((2, 0, 1))
            output = torch.from_numpy(np.array([
                pred,
            ])).float()
            output_ori = torch.cat([output_ori, output.cuda()], 1)

        # 预测竖直翻转
        img_flip = image_ori.transpose(Image.FLIP_TOP_BOTTOM)
        output = self.unetnested_predict(img_flip)
        pred = output.data.cpu().numpy()[0]
        pred = pred.transpose((1, 2, 0))
        pred = cv2.flip(pred, 0)
        pred = pred.transpose((2, 0, 1))
        output = torch.from_numpy(np.array([
            pred,
        ])).float()
        output_ori = torch.cat([output_ori, output.cuda()], 1)

        # 预测水平翻转
        img_flip = image_ori.transpose(Image.FLIP_LEFT_RIGHT)
        output = self.unetnested_predict(img_flip)
        pred = output.data.cpu().numpy()[0]
        pred = pred.transpose((1, 2, 0))
        pred = cv2.flip(pred, 1)
        pred = pred.transpose((2, 0, 1))
        output = torch.from_numpy(np.array([
            pred,
        ])).float()
        output_ori = torch.cat([output_ori, output.cuda()], 1)

        return output_ori
Example #30
0
def rotate():
    # retrieve parameters from html form
    angle = request.form['angle']
    filename = request.form['image']

    # open and process image
    target = os.path.join(APP_ROOT, 'static/images')
    destination = "/".join([target, filename])

    img = Image.open(destination)
    img = img.rotate(-1 * int(angle))

    # save and return image
    destination = "/".join([target, 'temp.png'])
    if os.path.isfile(destination):
        os.remove(destination)
    img.save(destination)

    return send_image('temp.png')
Example #31
0
    def make_feels_img(self, template: Image, colour: str, avatar: Image) -> BytesIO:
        # print(template.info)
        template = template.convert("RGBA")

        # avatar = Image.open(self.files + "temp." + ext)
        # transparency = template.split()[-1].getdata()
        data = np.array(template)
        red, green, blue, alpha = data.T
        blue_areas = (red == 0) & (blue == 255) & (green == 0) & (alpha == 255)
        data[..., :-1][blue_areas.T] = colour
        temp2 = Image.fromarray(data)
        temp2 = temp2.convert("RGBA")
        avatar = avatar.convert("RGBA")
        avatar = avatar.rotate(-30, expand=True)
        avatar = avatar.resize((60, 60), Image.ANTIALIAS)
        temp2.paste(avatar, (40, 25), avatar)
        temp = BytesIO()
        temp2.save(temp, format="PNG")
        temp.name = "feels.png"
        return temp
def write_image_with_rotations(
    image: Image,
    name: str,
    output_dir: Path,
    # raw_rotation: Union[None, int, list] = None,
) -> None:
    """
    Write image to disk along with the rotations
    """
    context_color = OVERMAP_TERRAIN_DATA.get(name)
    if context_color:
        pixels = image.load()
        height, width = image.size
        for col in range(height):
            for row in range(width):
                if pixels[col, row] in SCHEME['replace_with_context']:
                    pixels[col, row] = context_color

    image.save(output_dir / f'{name}.png')
    for rotation_suffix in ROTATIONS:
        image = image.rotate(-90)
        image.save(output_dir / f'{name}{rotation_suffix}.png')
Example #33
0
    def ShowAprilTag(self, id):
        try:
            filename = config.aprilTagRawName + str(id).zfill(5) + ".png"
            path = projectDir + "../" + config.aprilTagPath + filename
            rospy.loginfo("Showing TagID: " + str(id) + " with filename: " + filename)
            image = Image.open(path)

            if config.upsideDown:
                image = Image.rotate(180)

            self._display.ShowImage(image)

            self._currentID = id

            self.DumpSave()

            return True
        except ValueError:
            print("Could not convert data to the needed ID")
        except:
            print("Exception during ID-Change")
            return False
Example #34
0
def main():
    import sys
    import tornado.httpclient
    import tornado.options
    from tornado.options import define, options, parse_command_line

    define("operation", help="the operation to be performed", type=str,
           default="resize", metavar="|".join(["resize", "rotate", "none"]))
    define("width", help="the desired image width", type=int)
    define("height", help="the desired image height", type=int)
    define("mode", help="the resizing mode",
           metavar="|".join(Image.MODES), type=str)
    define("background", help="the hexidecimal fill background color",
           type=str)
    define("position", help="the crop position",
           metavar="|".join(Image.POSITIONS), type=str)
    define("filter", help="default filter to use when resizing",
           metavar="|".join(Image.FILTERS), type=str)
    define("degree", help="the desired rotation degree", type=int)
    define("expand", help="expand image size to accomodate rotation", type=int)
    define("rect", help="rectangle: x,y,w,h", type=str)
    define("format", help="default format to use when saving",
           metavar="|".join(Image.FORMATS), type=str)
    define("quality", help="default jpeg quality, 0-100", type=int)

    args = parse_command_line()
    if not args:
        print("Missing image source url")
        sys.exit()
    elif options.operation == "region":
        if not options.rect:
            tornado.options.print_help()
            sys.exit()
    elif options.operation == "resize":
        if not options.width and not options.height:
            tornado.options.print_help()
            sys.exit()
    elif options.operation == "rotate":
        if not options.degree:
            tornado.options.print_help()
            sys.exit()
    elif options.operation != "noop":
        tornado.options.print_help()
        sys.exit()

    if args[0].startswith("http://") or args[0].startswith("https://"):
        client = tornado.httpclient.HTTPClient()
        resp = client.fetch(args[0])
        image = Image(resp.buffer)
    else:
        image = Image(open(args[0], "r"))

    if options.operation == "resize":
        image.resize(options.width, options.height, mode=options.mode,
                     filter=options.filter, background=options.background,
                     position=options.position)
    elif options.operation == "rotate":
        image.rotate(options.degree, expand=options.expand)
    elif options.operation == "region":
        image.region(options.rect.split(","))

    stream = image.save(format=options.format, quality=options.quality)
    sys.stdout.write(stream.read())
    stream.close()