使用 PIL 裁剪图像时的背景颜色
Background color when cropping image with PIL
PIL.crop
的好处是,如果我们想在图像尺寸之外裁剪,它只适用于:
from PIL import Image
img = Image.open("test.jpg")
img.crop((-10, -20, 1000, 500)).save("output.jpg")
问题:如何将添加区域的背景颜色改为白色(默认:黑色)?
注:
如果可能,我想保留 crop
,避免像 Crop image, change black area if not not enough photo region in white 那样必须创建新图像并将裁剪后的图像粘贴到那里。
这里是 link 原始图像的下载:https://i.stack.imgur.com/gtA70.jpg(303x341 像素)
我认为一个函数调用是不可能的,因为相关的 C 函数似乎将目标图像内存区域清零(参见此处:https://github.com/python-pillow/Pillow/blob/master/src/libImaging/Crop.c#L47)
您提到对创建新图像并复制它不感兴趣,但我还是粘贴了那种解决方案以供参考:
from PIL import Image
img = Image.open("test.jpg")
x1, y1, x2, y2 = -10, -20, 1000, 500 # cropping coordinates
bg = Image.new('RGB', (x2 - x1, y2 - y1), (255, 255, 255))
bg.paste(img, (-x1, -y1))
bg.save("output.jpg")
输出:
使用PIL ImageOps
模块中的expand()
函数后,您就可以做您想做的事了。
from PIL import Image
from PIL import ImageOps
filename = 'C:/Users/Desktop/Maine_Coon_263.jpg'
img = Image.open(filename)
val = 10 #--- pixels to be cropped
#--- a new image with a border of 10 pixels on all sides
#--- also notice fill takes in the color of white as (255, 255, 255)
new_img = ImageOps.expand(img, border = val, fill = (255, 255, 255))
#--- cropping the image above will not result in any black portion
cropped = new_img.crop((val, val, 150, 150))
crop()
函数只接受一个参数,即要裁剪多少部分。当传入负值时,没有处理这种情况的功能。因此,在传递负值时,图像会以黑色像素填充。
使用 expand()
功能,您可以设置您选择的颜色,然后继续进行裁剪。
编辑
为了回应您的修改,我的想法有些天真,但它确实有效。
- 获取所有要裁剪的值的绝对值。您可以使用
numpy.abs()
.
- 接下来这些值中的最大值使用
numpy.max()
。
- 最终使用此值扩展图像并进行相应裁剪。
此代码将帮助您:
#--- Consider these values in a tuple that are to crop your image
crop_vals = (-10, -20, 1000, 500)
#--- get maximum value after obtaining the absolute of each
max_val = np.max(np.abs(crop_vals))
#--- add border to the image using this maximum value and crop
new_img = ImageOps.expand(img, border = max_val, fill = (255, 255, 255))
cropped = new_img.crop((max_val - 10, max_val - 20, new_img.size[0], new_img.size[1]))
PIL.crop
的好处是,如果我们想在图像尺寸之外裁剪,它只适用于:
from PIL import Image
img = Image.open("test.jpg")
img.crop((-10, -20, 1000, 500)).save("output.jpg")
问题:如何将添加区域的背景颜色改为白色(默认:黑色)?
注:
如果可能,我想保留
crop
,避免像 Crop image, change black area if not not enough photo region in white 那样必须创建新图像并将裁剪后的图像粘贴到那里。这里是 link 原始图像的下载:https://i.stack.imgur.com/gtA70.jpg(303x341 像素)
我认为一个函数调用是不可能的,因为相关的 C 函数似乎将目标图像内存区域清零(参见此处:https://github.com/python-pillow/Pillow/blob/master/src/libImaging/Crop.c#L47)
您提到对创建新图像并复制它不感兴趣,但我还是粘贴了那种解决方案以供参考:
from PIL import Image
img = Image.open("test.jpg")
x1, y1, x2, y2 = -10, -20, 1000, 500 # cropping coordinates
bg = Image.new('RGB', (x2 - x1, y2 - y1), (255, 255, 255))
bg.paste(img, (-x1, -y1))
bg.save("output.jpg")
输出:
使用PIL ImageOps
模块中的expand()
函数后,您就可以做您想做的事了。
from PIL import Image
from PIL import ImageOps
filename = 'C:/Users/Desktop/Maine_Coon_263.jpg'
img = Image.open(filename)
val = 10 #--- pixels to be cropped
#--- a new image with a border of 10 pixels on all sides
#--- also notice fill takes in the color of white as (255, 255, 255)
new_img = ImageOps.expand(img, border = val, fill = (255, 255, 255))
#--- cropping the image above will not result in any black portion
cropped = new_img.crop((val, val, 150, 150))
crop()
函数只接受一个参数,即要裁剪多少部分。当传入负值时,没有处理这种情况的功能。因此,在传递负值时,图像会以黑色像素填充。
使用 expand()
功能,您可以设置您选择的颜色,然后继续进行裁剪。
编辑
为了回应您的修改,我的想法有些天真,但它确实有效。
- 获取所有要裁剪的值的绝对值。您可以使用
numpy.abs()
. - 接下来这些值中的最大值使用
numpy.max()
。 - 最终使用此值扩展图像并进行相应裁剪。
此代码将帮助您:
#--- Consider these values in a tuple that are to crop your image
crop_vals = (-10, -20, 1000, 500)
#--- get maximum value after obtaining the absolute of each
max_val = np.max(np.abs(crop_vals))
#--- add border to the image using this maximum value and crop
new_img = ImageOps.expand(img, border = max_val, fill = (255, 255, 255))
cropped = new_img.crop((max_val - 10, max_val - 20, new_img.size[0], new_img.size[1]))