2010-10-06 5 views
2

Je voudrais créer une fonction, comme:Quel est le moyen le plus simple en Python pour redimensionner une image à une zone délimitée donnée?

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

Lorsqu'un fichier peut être donné et redimensionnée.

La fonction actuelle fonctionne très bien, sauf qu'elle ne recadre pas si nécessaire.

Dans le cas où une image rectangulaire est donnée, et un redimensionnement carré est nécessaire (largeur = hauteur), un recadrage centré devra être effectué.

Comment est-ce que je peux faire ceci?

Merci!

Répondre

4

Vous devez recadrer l'image correctement avant de le redimensionner. L'idée de base est de déterminer la plus grande surface rectangulaire de l'image source ayant le même rapport aspect/largeur que la vignette, puis de couper tout excès avant de redimensionner les dimensions de la vignette. Voici une fonction qui calcule la taille et l'emplacement d'une telle zone de culture:

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's dimensions 
      thumbwidth, thumbheight are thumbnail image's 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 compute half the size difference of the image & crop area 
    dx = (imagewidth-cropwidth)/2 
    dy = (imageheight-cropheight)/2 

    # return bounding box of crop area 
    return dx, dy, dx+cropwidth, dy+cropheight 

if __name__=='__main__': 

    print "===" 
    bbox = cropbbox(1024, 768, 128, 128) 
    print "cropbbox(1024, 768, 128, 128):", bbox 

    print "===" 
    bbox = cropbbox(768, 1024, 128, 128) 
    print "cropbbox(768, 1024, 128, 128):", bbox 

    print "===" 
    bbox = cropbbox(1024, 1024, 96, 128) 
    print "cropbbox(1024, 1024, 96, 128):", bbox 

    print "===" 
    bbox = cropbbox(1024, 1024, 128, 96) 
    print "cropbbox(1024, 1024, 128, 96):", bbox 

Après avoir déterminé la zone de culture, appelez im.crop(bbox) puis appelez im.thumbnail(...) sur l'image renvoyée.

+0

Hey, c'était vraiment utile. Merci beaucoup. – ensnare

+0

Vous pourriez éviter d'avoir à recadrer l'image originale en calculant la taille à l'échelle pour que le résultat corresponde aux limites de la vignette, mais ne le remplisse pas nécessairement complètement. – martineau

+0

Pour tout le monde intéressé, j'ai fait quelque chose de similaire en utilisant Ruby: http://stackoverflow.com/a/14917213/407213 – Dorian

0

Vous avez Image#crop. Est-ce votre question? ou comment calculer les coordonnées de la culture? (qui dépend de la façon dont vous voulez le faire)

Questions connexes