【问题标题】:ValueError: images do not match when blending pictures in PILValueError:在 PIL 中混合图片时图像不匹配
【发布时间】:2020-04-22 10:23:13
【问题描述】:

我一直在使用 python 来查看是否可以将两张图片“混合”在一起。我的意思是图像是透明的,你可以同时看到两张图片。如果这仍然没有意义,请查看此链接:(只有我会混合图片和图片而不是 gif)

https://cdn.discordapp.com/attachments/652564556211683363/662770085844221963/communism.gif

这是我的代码:

from PIL import Image

im1 = Image.open('oip.jpg')
im2 = Image.open('star.jpg')

bg = Image.blend(im1, im2, 0)
bg.save('star_oip_paste.jpg', quality=95)

我得到了错误:

line 6, in <module> bg = Image.blend(im1, im2, 0) ValueError: images do not match

我什至不确定我是否使用了正确的功能来将两张图像“混合”在一起 - 如果不是,请告诉我。

【问题讨论】:

标签: python python-imaging-library


【解决方案1】:

作为替代方案,您可以尝试使用 OpenCV(取决于您想要的输出)

    import cv2
 
# Read the images
     foreground = cv2.imread("puppets.png")
     background = cv2.imread("ocean.png")
     alpha = cv2.imread("puppets_alpha.png")
 
# Convert uint8 to float
     foreground = foreground.astype(float)
     background = background.astype(float)
 
# Normalize the alpha mask to keep intensity between 0 and 1
     alpha = alpha.astype(float)/255
 
# Multiply the foreground with the alpha matte
     foreground = cv2.multiply(alpha, foreground)
 
# Multiply the background with ( 1 - alpha )
     background = cv2.multiply(1.0 - alpha, background)
 
# Add the masked foreground and background.
     outImage = cv2.add(foreground, background)
 
# Display image
     cv2.imshow("outImg", outImage/255)
     cv2.waitKey(0)

【讨论】:

    【解决方案2】:

    这里发生了几件事:

    • 您的输入图像都是不支持透明度的 JPEG,因此您只能在整个图像中获得固定的混合。我的意思是你不能在一个点上看到一个图像,而在另一个点上看另一个图像。您只会在每个点看到相同比例的每个图像。这就是你想要的吗?

    例如,如果我拿帕丁顿和白金汉宫各取 50%:

    我明白了:

    如果这是您想要的,您需要将图像调整为通用大小并更改此行:

    bg = Image.blend(im1, im2, 0)
    

    bg = Image.blend(im1, im2, 0.5)          # blend half and half
    
    • 如果你想粘贴一些透明的东西,所以它只显示在某些地方,你需要从 GIF 或 PNG 加载具有透明度的叠加层并使用:

      background.paste(overlay, box=None, mask=overlay)

    然后您可以这样做 - 请注意,您可以在每个点看到不同数量的两个图像:

    因此,作为将透明图像叠加到不透明背景上的具体示例,并从帕丁顿 (400x400) 和这颗星 (500x500) 开始:

    #!/usr/bin/env python3
    
    from PIL import Image
    
    # Open background and foreground and ensure they are RGB (not palette)
    bg = Image.open('paddington.png').convert('RGB')
    fg = Image.open('star.png').convert('RGBA')
    
    # Resize foreground down from 500x500 to 100x100
    fg_resized = fg.resize((100,100))
    
    # Overlay foreground onto background at top right corner, using transparency of foreground as mask
    bg.paste(fg_resized,box=(300,0),mask=fg_resized)
    
    # Save result
    bg.save('result.png')
    

    如果你想从网站上抓取图片,使用这个:

    from PIL import Image 
    import requests 
    from io import BytesIO                                                                      
    
    # Grab the star image from this answer
    response = requests.get('https://i.stack.imgur.com/wKQCT.png')                              
    
    # Make it into a PIL image
    img = Image.open(BytesIO(response.content))  
    

    【讨论】:

    • 是的,我希望图像是透明的,所以谢谢。最后一个问题。我真的只是看到了 PIL,因为我想这样做,所以我不知道如何调整图片大小。你能大方地向我解释一下吗?谢谢。
    • 我已经通过调整大小和覆盖的具体示例为您更新了答案。
    • 不客气。请考虑通过单击计票旁边的 ✅ 来接受答案。问题(和答案)是免费的,所以如果您遇到困难并需要更多帮助,请回来。祝你好运!
    • 最后一个问题。有没有办法使用 PIL 从链接下载文件?或者可能是一种将链接中的图片和 jpg 图片混合的方法?
    • 我在最后添加了一个例子,使用requests模块。
    猜你喜欢
    • 2018-10-22
    • 2012-08-30
    • 1970-01-01
    • 2022-08-07
    • 2021-08-01
    • 2016-11-06
    • 2021-05-05
    • 1970-01-01
    • 2021-06-12
    相关资源
    最近更新 更多