Crop image with settable center and scale in Python PIL

依然范特西╮ 提交于 2019-12-11 06:58:17

问题


I would like to crop an image using PIL, although it could be some other module. I need the method to crop with a scale factor, ie 1.5 meaning that the output would be 1.5x zoomed in. Additionally, I would need to set the center where it zooms. This means setting x/2,y/2 as the center would zoom straight to the center, but other x,y values would zoom into those pixels.

If anyone knows how to do this I would really appreciate any help.

Right now I have some cropping working with ims = im.crop((int((x-x/i)/2), int((y-y/i)/2), int((x+(x/i))/2), int((y+(y/i))/2))) but that only zooms into the center, and "i" doesn't give a nice scale factor.

Again, that you for your help.


回答1:


It is just a matter of getting the center and the sizes right.

  1. Determine the center of the spot where you want to crop
  2. Determine the new size using the scale factor
  3. Determine the bounding box of the cropped image

The following script should do the trick.

import os.path
from PIL import Image

def get_img_dir():
    src_dir = os.path.dirname(__file__)
    img_dir = os.path.join(src_dir, '..', 'img')
    return img_dir

def open_img():
    img_dir = get_img_dir()
    img_name = 'amsterdam.jpg'
    full_img_path = os.path.join(img_dir, img_name)
    img = Image.open(full_img_path)
    return img

def crop_image(img, xy, scale_factor):
    '''Crop the image around the tuple xy

    Inputs:
    -------
    img: Image opened with PIL.Image
    xy: tuple with relative (x,y) position of the center of the cropped image
        x and y shall be between 0 and 1
    scale_factor: the ratio between the original image's size and the cropped image's size
    '''
    center = (img.size[0] * xy[0], img.size[1] * xy[1])
    new_size = (img.size[0] / scale_factor, img.size[1] / scale_factor)
    left = max (0, (int) (center[0] - new_size[0] / 2))
    right = min (img.size[0], (int) (center[0] + new_size[0] / 2))
    upper = max (0, (int) (center[1] - new_size[1] / 2))
    lower = min (img.size[1], (int) (center[1] + new_size[1] / 2))
    cropped_img = img.crop((left, upper, right, lower))
    return cropped_img

def save_img(img, img_name):
    img_dir = get_img_dir()
    full_img_path = os.path.join(img_dir, img_name)
    img.save(full_img_path)

if __name__ == '__main__':
    ams = open_img()

    crop_ams = crop_image(ams, (0.50, 0.50), 0.95)
    save_img(crop_ams, 'crop_amsterdam_01.jpg')

    crop_ams = crop_image(ams, (0.25, 0.25), 2.5)
    save_img(crop_ams, 'crop_amsterdam_02.jpg')

    crop_ams = crop_image(ams, (0.75, 0.45), 3.5)
    save_img(crop_ams, 'crop_amsterdam_03.jpg')

Original image:

crop_amsterdam_01.jpg:

crop_amsterdam_02.jpg:

crop_amsterdam_03.jpg:



来源:https://stackoverflow.com/questions/30832654/crop-image-with-settable-center-and-scale-in-python-pil

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!