如何在Python中使用PIL将图像合成到另一个图像?


77

我需要拍摄图像并将其放置在新的生成的白色背景上,以便将其转换为可下载的桌面墙纸。因此该过程将进行:

  1. 生成具有1440x900尺寸的新全白图像
  2. 将现有图像放在顶部居中
  3. 另存为单个图像

在PIL中,我看到了该ImageDraw对象,但是没有任何迹象表明它可以将现有的图像数据绘制到另一个图像上。任何人都可以推荐的建议或链接?

Answers:


140

这可以通过Image实例的paste方法来完成:

from PIL import Image
img = Image.open('/path/to/file', 'r')
img_w, img_h = img.size
background = Image.new('RGBA', (1440, 900), (255, 255, 255, 255))
bg_w, bg_h = background.size
offset = ((bg_w - img_w) // 2, (bg_h - img_h) // 2)
background.paste(img, offset)
background.save('out.png')

可以在Nadia Alramli的PIL教程中了解此PIL技巧和其他许多技巧


1
您可能需要根据模块/系统/版本进行导入:从PIL导入图像
Nuno Aniceto 2015年

3
感谢@NunoAniceto,我已对其进行from PIL import Image了更改,以使代码与Pillow更加兼容
unutbu

如果您使用的是Python 3.x,请检查stackoverflow.com/a/17530159/7326714修复“ offeset”元组整数错误。
LucSpan

9

根据unutbus答案:

#!/usr/bin/env python

from PIL import Image
import math


def resize_canvas(old_image_path="314.jpg", new_image_path="save.jpg",
                  canvas_width=500, canvas_height=500):
    """
    Place one image on another image.

    Resize the canvas of old_image_path and store the new image in
    new_image_path. Center the image on the new canvas.
    """
    im = Image.open(old_image_path)
    old_width, old_height = im.size

    # Center the image
    x1 = int(math.floor((canvas_width - old_width) / 2))
    y1 = int(math.floor((canvas_height - old_height) / 2))

    mode = im.mode
    if len(mode) == 1:  # L, 1
        new_background = (255)
    if len(mode) == 3:  # RGB
        new_background = (255, 255, 255)
    if len(mode) == 4:  # RGBA, CMYK
        new_background = (255, 255, 255, 255)

    newImage = Image.new(mode, (canvas_width, canvas_height), new_background)
    newImage.paste(im, (x1, y1, x1 + old_width, y1 + old_height))
    newImage.save(new_image_path)

resize_canvas()

请记住,请使用Pillow(文档GitHubPyPI)而不是python-imaging,因为Pillow可与Python 2.X和Python 3.X一起使用。


3

这是做类似的事情

我开始的地方是在photoshop中生成“白色背景”并将其导出为PNG文件。那就是我得到im1的地方(图1)。然后使用粘贴功能,因为这样更容易。

from PIL import Image

im1 = Image.open('image/path/1.png')
im2 = Image.open('image/path/2.png')
area = (40, 1345, 551, 1625)  
im1.paste(im2, area)
                   l>(511+40) l>(280+1345)
         |    l> From 0 (move, 1345px down) 
          -> From 0 (top left, move 40 pixels right)

Okay so where did these #'s come from? (40, 1345, 551, 1625) im2.size (511, 280) Because I added 40 right and 1345 down (40, 1345, 511, 280) I must add them to the original image size which = (40, 1345, 551, 1625)

im1.show() 

显示你的新形象


0

Image.blend()?[链接]

或者,更好的是Image.paste(),相同的链接。


“通过在给定图像之间使用恒定的alpha值进行插值来创建新图像。两个图像必须具有相同的大小和模式。” 从文档看来,它们的大小不能相同。
塞巴斯蒂安

我也注意到Image.paste()了,这最终是解决方案。
Felix

该网址已过期
Phani Rithvij

0

也许为时已晚,但是对于此类图像操作,我们确实在模型中使用了具有原始图像的ImageSpecField [ link ]。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.