Як скласти зображення на інше зображення за допомогою PIL у Python?


81

Мені потрібно зробити зображення та розмістити його на новому, згенерованому білому фоні, щоб воно перетворилося на шпалери робочого столу, які можна завантажити. Отже, процес тривав би:

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

У PIL я бачу ImageDrawоб'єкт, але ніщо не вказує на те, що він може намалювати наявні дані зображення на інше зображення. Пропозиції чи посилання, які може порекомендувати будь-хто?

Відповіді:


145

Цього можна досягти за допомогою 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 можна знайти в Навчальному посібнику Наді Альрамлі


1
Можливо, вам доведеться імпортувати залежно від вашого модуля / системи / версії: з імпорту PIL Зображення
Nuno Aniceto

3
Дякую @NunoAniceto, я змінив його на, from PIL import Imageщоб зробити код більш сумісним з Pillow .
unutbu

Якщо ви використовуєте Python 3.x, перевірте stackoverflow.com/a/17530159/7326714, щоб виправити помилку цілочисельного набору кортежів "prekrшити".
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 ( Documentation , GitHub , PyPI ) замість python-візуалізації, оскільки Pillow працює з Python 2.X та Python 3.X.


3

Це для того, щоб зробити щось подібне

Там, де я почав, було створення цього "білого тла" у фотошопі та експортування його у файл 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(), те саме посилання.


"Створює нове зображення шляхом інтерполяції між даними зображеннями, використовуючи константу альфа-версії. Обидва зображення повинні мати однаковий розмір і режим." З документації видно, що вони не можуть бути різного розміру.
Себастьян,

Я також зауважив Image.paste(), що, зрештою, було рішенням.
Фелікс,

1
Термін дії URL-адреси закінчився
Phani Rithvij

0

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.