简体   繁体   English

在Python PIL中使用可设置的中心和缩放裁剪图像

[英]Crop image with settable center and scale in Python PIL

I would like to crop an image using PIL, although it could be some other module. 我想使用PIL裁剪图像,尽管它可能是其他模块。 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. 我需要使用缩放因子裁剪方法,即1.5意味着输出将放大1.5倍。此外,我需要设置缩放中心。 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. 这意味着设置x / 2,y / 2,因为中心将直接缩放到中心,但其他x,y值将放大到这些像素。

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((xx/i)/2), int((yy/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. 现在我有一些裁剪使用ims = im.crop((int((xx / i)/ 2),int((yy / i)/ 2),int((x +(x / i))/ 2) ,int((y +(y / i))/ 2)))但是只放大到中心,“i”没有给出一个很好的比例因子。

Again, that you for your help. 再次,那是你的帮助。

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: 原始图片: amsterdam.jpg

crop_amsterdam_01.jpg: crop_amsterdam_01.jpg: crop_amsterdam_01.jpg

crop_amsterdam_02.jpg: crop_amsterdam_02.jpg: crop_amsterdam_02.jpg

crop_amsterdam_03.jpg: crop_amsterdam_03.jpg: crop_amsterdam_03.jpg

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM