Как вы комбинируете изображение на другое изображение с PIL в Python? - PullRequest
60 голосов
/ 02 апреля 2010

Мне нужно взять изображение и поместить его на новый сгенерированный белый фон, чтобы оно могло быть преобразовано в загружаемые обои для рабочего стола. Таким образом, процесс будет идти:

  1. Создание нового полностью белого изображения с размерами 1440x900
  2. Поместите существующее изображение сверху, по центру
  3. Сохранить как одно изображение

В PIL я вижу объект ImageDraw, но ничто не указывает на то, что он может нарисовать существующие данные изображения на другое изображение. Предложения или ссылки кто-нибудь может порекомендовать?

Ответы [ 5 ]

109 голосов
/ 02 апреля 2010

Это можно сделать с помощью метода paste экземпляра Image:

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')

Этот и многие другие трюки PIL можно найти на Учебник Надии Алрамли

7 голосов
/ 05 января 2015

На основании ответа 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 ( Документация , GitHub , PyPI ) вместо Python-Imaging, поскольку Pillow работает с Python 2.X и Python 3.X .

2 голосов
/ 05 марта 2017

Это что-то похожее

Я начал с создания «белого фона» в фотошопе и экспортировал его в файл 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() 

чтобы показать ваше новое изображение

1 голос
/ 02 апреля 2010

Image.blend()? [ ссылка ]

Или, еще лучше, Image.paste(), та же ссылка.

0 голосов
/ 30 октября 2013

Возможно, слишком поздно, но для таких операций с изображениями мы используем ImageSpecField [ ссылка ] в модели с исходным изображением.

...