2009-10-15 9 views
17

Probablemente estoy buscando algo incorrecto en el manual, pero estoy buscando tomar un objeto de imagen y expandirlo sin cambiar el tamaño (estiramiento/aplastamiento) de la imagen original.En Python, Python Image Library 1.1.6, ¿cómo puedo expandir el lienzo sin cambiar el tamaño?

Ejemplo de juguete: imagina un rectángulo azul, 200 x 100, luego realizo alguna operación y tengo un nuevo objeto de imagen, 400 x 300, que consiste en un fondo blanco sobre el cual descansa un rectángulo azul de 200 x 100. Bonificación si puedo controlar en qué dirección se expande, o el nuevo color de fondo, etc.

Básicamente, tengo una imagen que añadiré de forma iterativa, y no sé qué tamaño será al principio .

Supongo que sería posible para mí agarrar el objeto original, hacer un objeto nuevo, un poco más grande, pegar el original allí, dibujar un poco más, luego repetir. Parece que podría ser computacionalmente costoso. Sin embargo, pensé que habría una función para esto, ya que supongo que es una operación común. Quizás asumí que estaba equivocado.

Respuesta

23

La función ImageOps.expand expandirá la imagen, pero agrega la misma cantidad de píxeles en cada dirección.

La mejor manera es simplemente para hacer una nueva imagen y pegar:

newImage = Image.new(mode, (newWidth,newHeight)) 
newImage.paste(srcImage, (x1,y1,x1+oldWidth,y1+oldHeight)) 

Si el rendimiento es un problema, hacer que su imagen original más grande que necesitaba y recortarla después de que el dibujo se hace.

+0

Si la imagen tiene una paleta ('srcImage.mode ==" P "'), la paleta debe copiarse también: 'newImage.putpalette (srcImage.palette.getdata() [1])'. –

4

Tal vez debas considerar un enfoque bastante diferente para tu imagen ... construirlo con azulejos de un tamaño fijo. De esa manera, como necesita expandirse, solo agrega nuevos mosaicos de imágenes. Cuando hayas completado todos tus cálculos, puedes determinar el tamaño final de la imagen, crear una imagen en blanco de ese tamaño y pegar los mosaicos en ella. Eso debería reducir la cantidad de copia que está buscando para completar la tarea.

(Te probable es que desee encapsular una imagen tan azulejos en un objeto que ocultaba los aspectos del embaldosado de las otras capas de código, por supuesto.)

+0

+1 el procesamiento de imagen más escalable se realiza en mosaico. – whatnick

7

Basado en interjays respuesta:

#!/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): 
    """ 
    Resize the canvas of old_image_path. 

    Store the new image in new_image_path. Center the image on the new canvas. 

    Parameters 
    ---------- 
    old_image_path : str 
    new_image_path : str 
    canvas_width : int 
    canvas_height : int 
    """ 
    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() 
Cuestiones relacionadas