使用 Python / PIL 进行多边形裁剪/剪辑
Posted
技术标签:
【中文标题】使用 Python / PIL 进行多边形裁剪/剪辑【英文标题】:Polygon crop/clip using Python / PIL 【发布时间】:2014-03-23 07:11:23 【问题描述】:客户端将多边形点与未切割的原始图像一起发送到服务器。
有没有一种方法可以在 Python 服务器中沿这些点剪辑(裁剪)原始图像,并保存裁剪后的图像? 我目前正在使用 PIL,并且更喜欢 PIL 或 PIL 扩展解决方案。
提前致谢
【问题讨论】:
【参考方案1】:我找到了一个使用 numpy 和 PIL 的解决方案——所以我想我会分享:
import numpy
from PIL import Image, ImageDraw
# read image as RGB and add alpha (transparency)
im = Image.open("crop.jpg").convert("RGBA")
# convert to numpy (for convenience)
imArray = numpy.asarray(im)
# create mask
polygon = [(444,203),(623,243),(691,177),(581,26),(482,42)]
maskIm = Image.new('L', (imArray.shape[1], imArray.shape[0]), 0)
ImageDraw.Draw(maskIm).polygon(polygon, outline=1, fill=1)
mask = numpy.array(maskIm)
# assemble new image (uint8: 0-255)
newImArray = numpy.empty(imArray.shape,dtype='uint8')
# colors (three first columns, RGB)
newImArray[:,:,:3] = imArray[:,:,:3]
# transparency (4th column)
newImArray[:,:,3] = mask*255
# back to Image from numpy
newIm = Image.fromarray(newImArray, "RGBA")
newIm.save("out.png")
【讨论】:
如果用透明度裁剪PNG,请使用mask = mask*255; newImArray[:,:,3] = [[imArray[:, :, 3][i][j] if mask[i][j] == 255 else mask[i][j] for j in range(len(mask[i]))] for i in range(len(mask))]
替换newImArray[:,:,3] = mask*255
。【参考方案2】:
我执行此代码是为了裁剪由多边形定义的图像区域。
from PIL import Image, ImageDraw
original = Image.open("original.jpg")
xy = [(100,100),(1000,100),(1000,800),(100,800)]
mask = Image.new("L", original.size, 0)
draw = ImageDraw.Draw(mask)
draw.polygon(xy, fill=255, outline=None)
black = Image.new("L", original.size, 0)
result = Image.composite(original, black, mask)
result.save("result.jpg")
【讨论】:
如果您需要裁剪图像的所有三个通道,只需提及将black = Image.new("L", original.size, 0)
更改为 black = Image.new("RGB", original.size, 0)
感谢您的来信!【参考方案3】:
基于@user2667409 的答案的另一种解决方案, 它使用每个元素 1 位来表示掩码,并将最终结果导出为 JPEG 格式。
import numpy
from PIL import Image, ImageDraw
# read image as RGB (without alpha)
img = Image.open("crop.jpg").convert("RGB")
# convert to numpy (for convenience)
img_array = numpy.asarray(img)
# create mask
polygon = [(444,203),(623,243),(691,177),(581,26),(482,42)]
# create new image ("1-bit pixels, black and white", (width, height), "default color")
mask_img = Image.new('1', (img_array.shape[1], img_array.shape[0]), 0)
ImageDraw.Draw(mask_img).polygon(polygon, outline=1, fill=1)
mask = numpy.array(mask_img)
# assemble new image (uint8: 0-255)
new_img_array = numpy.empty(img_array.shape, dtype='uint8')
# copy color values (RGB)
new_img_array[:,:,:3] = img_array[:,:,:3]
# filtering image by mask
new_img_array[:,:,0] = new_img_array[:,:,0] * mask
new_img_array[:,:,1] = new_img_array[:,:,1] * mask
new_img_array[:,:,2] = new_img_array[:,:,2] * mask
# back to Image from numpy
newIm = Image.fromarray(new_img_array, "RGB")
newIm.save("out.jpg")
【讨论】:
以上是关于使用 Python / PIL 进行多边形裁剪/剪辑的主要内容,如果未能解决你的问题,请参考以下文章