2010-04-01 19 views
39

Necesito tomar una imagen y colocarla en un nuevo fondo blanco generado para que se convierta en un fondo de escritorio descargable. Así que el proceso iría:¿Cómo se compone una imagen en otra imagen con PIL en Python?

  1. Crear nuevo, todas las imágenes blancas con 1440x900 dimensiones de imagen existente
  2. lugar encima, centrada
  3. Guardar como una sola imagen

En PIL, veo el ImageDraw objeto, pero nada indica que pueda dibujar los datos de imagen existentes en otra imagen. ¿Sugerencias o enlaces que cualquiera puede recomendar?

Respuesta

73

Esto se puede lograr con paste método de una instancia de archivo:

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

Esto y muchos otros trucos PIL puede ser recogido en Nadia Alramli's PIL Tutorial

+0

Es posible que deba importar según su módulo/sistema/versión: desde la importación de PIL Image –

+1

Gracias @NunoAniceto, lo he cambiado a 'from PIL import Image' para hacer que el código sea más [compatible con Pillow] (http: //pillow.readthedocs.org/en/latest/porting-pil-to-pillow.html). – unutbu

+0

Si está utilizando Python 3.x, compruebe https://stackoverflow.com/a/17530159/7326714 para corregir el error de número entero de tupla 'offeset'. – LucSpan

0

Image.blend()? [link]

O, mejor aún, Image.paste(), mismo enlace.

+0

"crea una nueva imagen mediante interpolación entre las imágenes dadas, utilizando una constante alfa. Ambas imágenes debe tener el mismo tamaño y modo ". De la documentación, parece que no pueden ser de diferentes tamaños. – Sebastian

+0

Anoté 'Image.paste()', también, que finalmente fue la solución. – Felix

0

Tal vez demasiado tarde, pero para las operaciones de tales imágenes, que hacemos use ImageSpecField [link] en el modelo con la imagen original.

5

Basado en respuesta 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() 

recuerde utilizar Almohada (Documentation, GitHub, PyPI) en lugar de pitón de imágenes como almohada funciona con 2.X Python y Python 3.X.

1

Esto es para hacer algo similar

Cuando empecé era mediante la generación que 'fondo blanco' en photoshop y exportarlo como un archivo PNG. Es de donde obtuve im1 (Imagen 1). Luego usó la función de pegar porque es mucho más fácil.

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

para mostrar su nueva imagen

Cuestiones relacionadas