PIL在图像上绘制半透明方形叠加

时间:2017-04-25 19:02:16

标签: python python-3.x python-imaging-library pillow

from PIL import Image
from PIL import ImageDraw 
from io import BytesIO
from urllib.request import urlopen

url = "https://i.ytimg.com/vi/W4qijIdAPZA/maxresdefault.jpg"
file = BytesIO(urlopen(url).read())
img = Image.open(file)
img = img.convert("RGBA")
draw = ImageDraw.Draw(img, "RGBA")
draw.rectangle(((0, 00), (img.size[0], img.size[1])), fill=(0,0,0,127))
img.save('dark-cat.jpg')

这给了我一个巨大的黑色方块。我希望它是一个带有猫的半透明黑色方形。任何想法?

3 个答案:

答案 0 :(得分:12)

对不起,显然这不是一个错误,正如我原先想的那样。

您可以通过创建临时图片并使用Image.alpha_composite()来执行此操作,如下所示:

from PIL import Image
from PIL import ImageDraw
from io import BytesIO
from urllib.request import urlopen

url = "https://i.ytimg.com/vi/W4qijIdAPZA/maxresdefault.jpg"
file = BytesIO(urlopen(url).read())
img = Image.open(file)
img = img.convert("RGBA")

# Make a blank image for the rectangle, initialized to a completely
# transparent color.
tmp = Image.new('RGBA', img.size, (0,0,0,0))

# Create a drawing context for it.
draw = ImageDraw.Draw(tmp)

# Determine the bounding box of the largest possible semi-transparent
# square rectangle centered on the temporary image and draw it.
if img.size[0] > img.size[1]:
    size = img.size[1]
    llx, lly = (img.size[0] - img.size[1]) // 2, 0
else:
    size = img.size[0]
    llx, lly = 0, (img.size[1] - img.size[0]) // 2

# Add one to upper point because second point is just outside the drawn
# rectangle.
urx, ury = llx + size + 1, lly + size + 1
draw.rectangle(((llx, lly), (urx, ury)), fill=(0,0,0,127))

# Alpha composite the two images together.
img = Image.alpha_composite(img, tmp)
img = img.convert("RGB") # Remove alpha for saving in jpg format.
img.save('dark-cat.jpg')
img.show()

以下是您的测试图片的结果:

darken picture of a cat

答案 1 :(得分:2)

考虑到每当我想用PIL绘制透明矩形时,我都会不断回到这个问题,所以我决定进行更新。

如果我只更改一件事,您的代码将为我工作:将图像保存为PNG格式而不是JPEG。

所以当我跑步时

from io import BytesIO
from urllib.request import urlopen
from PIL import Image
from PIL import ImageDraw

url = "https://i.ytimg.com/vi/W4qijIdAPZA/maxresdefault.jpg"
file = BytesIO(urlopen(url).read())
img = Image.open(file)
draw = ImageDraw.Draw(img, "RGBA")
draw.rectangle(((280, 10), (1010, 706)), fill=(200, 100, 0, 127))
draw.rectangle(((280, 10), (1010, 706)), outline=(0, 0, 0, 127), width=3)
img.save('orange-cat.png')

我得到这张精美的照片:

cat with semi-transparent orange bounding box

答案 2 :(得分:0)

如果您只想调暗整个图像,可以采用更简单的方法:

img = Image.eval(img, lambda x: x/2)