Pregunta

Me gustaría crear una función, como:

def generateThumbnail(self, width, height):
     """
     Generates thumbnails for an image
     """
     im = Image.open(self._file)
     im.thumbnail((width, height), Image.ANTIALIAS)
     im.save(self._path + str(width) + 'x' + 
             str(height) + '-' + self._filename, "JPEG")

Cuando un archivo se puede dar y cambiar de tamaño.

La función actual funciona muy bien excepto que no aflora cuando sea necesario.

En el caso de que se le da una imagen rectangular, y un cambio de tamaño cuadrado se requiere (width = altura), algún recorte centrado-ponderada tendrá que ser hecho.

¿Fue útil?

Solución

Se necesita recortar la imagen correctamente antes de cambiar su tamaño. La idea básica es determinar la mayor área rectangular de la imagen de origen que tienen el mismo aspecto (anchura a altura) Relación de la imagen en miniatura como y luego recortar (cultivo) cualquier exceso de alrededor de él antes de cambiar el tamaño a las dimensiones de la imagen en miniatura). He aquí una función que calcule el tamaño y la ubicación de una de esas áreas de cultivo:

def cropbbox(imagewidth,imageheight, thumbwidth,thumbheight):
    """ cropbbox(imagewidth,imageheight, thumbwidth,thumbheight)

        Compute a centered image crop area for making thumbnail images.
          imagewidth,imageheight are source image dimensions
          thumbwidth,thumbheight are thumbnail image dimensions

        Returns bounding box pixel coordinates of the cropping area
        in this order (left,upper, right,lower).
    """
    # determine scale factor
    fx = float(imagewidth)/thumbwidth
    fy = float(imageheight)/thumbheight
    f = fx if fx < fy else fy

    # calculate size of crop area
    cropheight,cropwidth = int(thumbheight*f),int(thumbwidth*f)

    # for centering use half the size difference of the image and the crop area
    dx = (imagewidth-cropwidth)/2
    dy = (imageheight-cropheight)/2

    # return bounding box of centered crop area on source image
    return dx,dy, cropwidth+dx,cropheight+dy


if __name__=='__main__':

    print("===")
    bbox = cropbbox(1024,768, 128,128)
    print("cropbbox(1024,768, 128,128): {}".format(bbox))

    print("===")
    bbox = cropbbox(768,1024, 128,128)
    print("cropbbox(768,1024, 128,128): {}".format(bbox))

    print("===")
    bbox = cropbbox(1024,1024, 96,128)
    print("cropbbox(1024,1024, 96,128): {}".format(bbox))

    print("===")
    bbox = cropbbox(1024,1024, 128,96)
    print("cropbbox(1024,1024, 128,96): {}".format(bbox))

Después de determinar el área de recorte, im.crop(bbox) llamada y im.thumbnail(...) entonces llamada en la imagen devuelta.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top