web-dev-qa-db-fra.com

Comment composez-vous une image sur une autre image avec PIL en Python?

Je dois prendre une image et la placer sur un nouveau fond blanc généré afin de la convertir en fond d'écran téléchargeable. Donc, le processus irait:

  1. Générez une nouvelle image entièrement blanche aux dimensions 1440x900
  2. Placer l'image existante sur le dessus, centrée
  3. Enregistrer en tant qu'image unique

Dans PIL, je vois l'objet ImageDraw, mais rien n'indique qu'il peut dessiner des données d'image existantes sur une autre image. Suggestions ou liens que n'importe qui peut recommander?

61
Sebastian

Cela peut être accompli avec la méthode paste d'une instance 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')

Ceci et bien d'autres astuces PIL peuvent être récupérés à Nadia Alramli's PIL Tutorial

112
unutbu

Basé sur la réponse 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()

N'oubliez pas d'utiliser Pillow ( Documentation , GitHub , PyPI ) au lieu de l'imagerie python car Pillow fonctionne avec Python = 2.X et Python 3.X.

7
Martin Thoma

C'est pour faire quelque chose de similaire

J'ai commencé par générer ce "fond blanc" dans Photoshop et l'exporter en tant que fichier PNG. C'est là que j'ai obtenu im1 (Image 1). Ensuite, j'ai utilisé la fonction coller car c'est beaucoup plus facile.

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

pour montrer votre nouvelle image

2
Steven Jeffers

Image.blend()? [ lien ]

Ou, mieux encore, Image.paste(), même lien.

1
Felix

Peut-être trop tard, mais pour de telles opérations d'image, nous utilisons ImageSpecField [ link ] dans le modèle avec l'image d'origine.

0
profuel