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.
Hey, c'était vraiment utile. Merci beaucoup. – ensnare
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
Pour tout le monde intéressé, j'ai fait quelque chose de similaire en utilisant Ruby: http://stackoverflow.com/a/14917213/407213 – Dorian