Existe-t-il un moyen évident de faire cela qui me manque? J'essaie juste de faire des miniatures.
Existe-t-il un moyen évident de faire cela qui me manque? J'essaie juste de faire des miniatures.
Réponses:
Définissez une taille maximale. Ensuite, calculez un rapport de redimensionnement en prenant min(maxwidth/width, maxheight/height)
.
La bonne taille est oldsize*ratio
.
Il y a bien sûr aussi une méthode de bibliothèque pour ce faire: la méthode Image.thumbnail
.
Voici un exemple (modifié) de la documentation PIL .
import os, sys
import Image
size = 128, 128
for infile in sys.argv[1:]:
outfile = os.path.splitext(infile)[0] + ".thumbnail"
if infile != outfile:
try:
im = Image.open(infile)
im.thumbnail(size, Image.ANTIALIAS)
im.save(outfile, "JPEG")
except IOError:
print "cannot create thumbnail for '%s'" % infile
s= img.size(); ratio = MAXWIDTH/s[0]; newimg = img.resize((s[0]*ratio, s[1]*ratio), Image.ANTIALIAS)
? (c'est pour la division en virgule flottante cependant :)
ANTIALIAS
n'est plus préféré pour les utilisateurs de la populaire fourchette Pillow de PIL. pillow.readthedocs.org/en/3.0.x/releasenotes/…
thumbnail
ne fonctionne que si l'image résultante est plus petite que l'image d'origine. Pour cette raison, je suppose que l'utilisation resize
est la meilleure façon.
Ce script redimensionnera une image (somepic.jpg) à l'aide de PIL (Python Imaging Library) à une largeur de 300 pixels et une hauteur proportionnelle à la nouvelle largeur. Pour ce faire, il détermine le pourcentage de 300 pixels de la largeur d'origine (img.size [0]), puis multiplie la hauteur d'origine (img.size [1]) par ce pourcentage. Remplacez «basewidth» par tout autre nombre pour modifier la largeur par défaut de vos images.
from PIL import Image
basewidth = 300
img = Image.open('somepic.jpg')
wpercent = (basewidth/float(img.size[0]))
hsize = int((float(img.size[1])*float(wpercent)))
img = img.resize((basewidth,hsize), Image.ANTIALIAS)
img.save('sompic.jpg')
sompic.jpg
. Pourquoi cela arrive-t-il? J'utilise Python 3.x
.jpeg
, utilisez img.save('sompic.jpg', 'JPEG')
.
PIL.Image.ANTIALIAS
option pour resize
, devrait en fait être PIL.Image.LANCZOS
, bien qu'ils soient tous les deux 1
en valeur, voir pillow.readthedocs.io/en/3.1.x/reference/…
Je recommande également d'utiliser la méthode des miniatures de PIL, car elle vous supprime tous les problèmes de rapport.
Un indice important, cependant: remplacer
im.thumbnail(size)
avec
im.thumbnail(size,Image.ANTIALIAS)
par défaut, PIL utilise le filtre Image.NEAREST pour le redimensionnement, ce qui se traduit par de bonnes performances mais une mauvaise qualité.
Image.thumbnail
.
Basé à @tomvon, j'ai fini d'utiliser les éléments suivants (choisissez votre cas):
a) Hauteur de redimensionnement ( je connais la nouvelle largeur, j'ai donc besoin de la nouvelle hauteur )
new_width = 680
new_height = new_width * height / width
b) Largeur de redimensionnement ( je connais la nouvelle hauteur, j'ai donc besoin de la nouvelle largeur )
new_height = 680
new_width = new_height * width / height
Alors juste:
img = img.resize((new_width, new_height), Image.ANTIALIAS)
resize
appel, vous utilisez à la new_width
fois la hauteur et la largeur?
from PIL import Image
img = Image.open('/your image path/image.jpg') # image extension *.png,*.jpg
new_width = 200
new_height = 300
img = img.resize((new_width, new_height), Image.ANTIALIAS)
img.save('output image name.png') # format may what you want *.png, *jpg, *.gif
Si vous essayez de conserver le même rapport hauteur / largeur, ne redimensionneriez-vous pas un certain pourcentage de la taille d'origine?
Par exemple, la moitié de la taille d'origine
half = 0.5
out = im.resize( [int(half * s) for s in im.size] )
from PIL import Image
from resizeimage import resizeimage
def resize_file(in_file, out_file, size):
with open(in_file) as fd:
image = resizeimage.resize_thumbnail(Image.open(fd), size)
image.save(out_file)
image.close()
resize_file('foo.tif', 'foo_small.jpg', (256, 256))
J'utilise cette bibliothèque:
pip install python-resize-image
Juste mettre à jour cette question avec un wrapper plus moderne Cette bibliothèque enveloppe Pillow (une fourchette de PIL) https://pypi.org/project/python-resize-image/
Vous permettant de faire quelque chose comme ça: -
from PIL import Image
from resizeimage import resizeimage
fd_img = open('test-image.jpeg', 'r')
img = Image.open(fd_img)
img = resizeimage.resize_width(img, 200)
img.save('test-image-width.jpeg', img.format)
fd_img.close()
Des tas d'autres exemples dans le lien ci-dessus.
J'essayais de redimensionner certaines images pour un diaporama vidéo et à cause de cela, je ne voulais pas seulement une dimension maximale, mais une largeur maximale et une hauteur maximale (la taille de l'image vidéo).
Et il y avait toujours la possibilité d'une vidéo portrait ...
La Image.thumbnail
méthode était prometteuse, mais je ne pouvais pas la faire monter en gamme une image plus petite.
Donc, après que je n'ai pas trouvé de moyen évident de le faire ici (ou à d'autres endroits), j'ai écrit cette fonction et l'ai mise ici pour celles à venir:
from PIL import Image
def get_resized_img(img_path, video_size):
img = Image.open(img_path)
width, height = video_size # these are the MAX dimensions
video_ratio = width / height
img_ratio = img.size[0] / img.size[1]
if video_ratio >= 1: # the video is wide
if img_ratio <= video_ratio: # image is not wide enough
width_new = int(height * img_ratio)
size_new = width_new, height
else: # image is wider than video
height_new = int(width / img_ratio)
size_new = width, height_new
else: # the video is tall
if img_ratio >= video_ratio: # image is not tall enough
height_new = int(width / img_ratio)
size_new = width, height_new
else: # image is taller than video
width_new = int(height * img_ratio)
size_new = width_new, height
return img.resize(size_new, resample=Image.LANCZOS)
Une méthode simple pour garder des rapports contraints et passer une largeur / hauteur maximale. Pas le plus joli mais fait le travail et est facile à comprendre:
def resize(img_path, max_px_size, output_folder):
with Image.open(img_path) as img:
width_0, height_0 = img.size
out_f_name = os.path.split(img_path)[-1]
out_f_path = os.path.join(output_folder, out_f_name)
if max((width_0, height_0)) <= max_px_size:
print('writing {} to disk (no change from original)'.format(out_f_path))
img.save(out_f_path)
return
if width_0 > height_0:
wpercent = max_px_size / float(width_0)
hsize = int(float(height_0) * float(wpercent))
img = img.resize((max_px_size, hsize), Image.ANTIALIAS)
print('writing {} to disk'.format(out_f_path))
img.save(out_f_path)
return
if width_0 < height_0:
hpercent = max_px_size / float(height_0)
wsize = int(float(width_0) * float(hpercent))
img = img.resize((max_px_size, wsize), Image.ANTIALIAS)
print('writing {} to disk'.format(out_f_path))
img.save(out_f_path)
return
Voici un script python qui utilise cette fonction pour exécuter le redimensionnement d'image par lots.
Ont mis à jour la réponse ci-dessus par "tomvon"
from PIL import Image
img = Image.open(image_path)
width, height = img.size[:2]
if height > width:
baseheight = 64
hpercent = (baseheight/float(img.size[1]))
wsize = int((float(img.size[0])*float(hpercent)))
img = img.resize((wsize, baseheight), Image.ANTIALIAS)
img.save('resized.jpg')
else:
basewidth = 64
wpercent = (basewidth/float(img.size[0]))
hsize = int((float(img.size[1])*float(wpercent)))
img = img.resize((basewidth,hsize), Image.ANTIALIAS)
img.save('resized.jpg')
Mon vilain exemple.
La fonction récupère le fichier comme: "pic [0-9a-z]. [Extension]", les redimensionne à 120x120, déplace la section au centre et l'enregistre dans "ico [0-9a-z]. [Extension]", fonctionne avec portrait et paysage:
def imageResize(filepath):
from PIL import Image
file_dir=os.path.split(filepath)
img = Image.open(filepath)
if img.size[0] > img.size[1]:
aspect = img.size[1]/120
new_size = (img.size[0]/aspect, 120)
else:
aspect = img.size[0]/120
new_size = (120, img.size[1]/aspect)
img.resize(new_size).save(file_dir[0]+'/ico'+file_dir[1][3:])
img = Image.open(file_dir[0]+'/ico'+file_dir[1][3:])
if img.size[0] > img.size[1]:
new_img = img.crop( (
(((img.size[0])-120)/2),
0,
120+(((img.size[0])-120)/2),
120
) )
else:
new_img = img.crop( (
0,
(((img.size[1])-120)/2),
120,
120+(((img.size[1])-120)/2)
) )
new_img.save(file_dir[0]+'/ico'+file_dir[1][3:])
J'ai redimensionné l'image de cette manière et ça fonctionne très bien
from io import BytesIO
from django.core.files.uploadedfile import InMemoryUploadedFile
import os, sys
from PIL import Image
def imageResize(image):
outputIoStream = BytesIO()
imageTemproaryResized = imageTemproary.resize( (1920,1080), Image.ANTIALIAS)
imageTemproaryResized.save(outputIoStream , format='PNG', quality='10')
outputIoStream.seek(0)
uploadedImage = InMemoryUploadedFile(outputIoStream,'ImageField', "%s.jpg" % image.name.split('.')[0], 'image/jpeg', sys.getsizeof(outputIoStream), None)
## For upload local folder
fs = FileSystemStorage()
filename = fs.save(uploadedImage.name, uploadedImage)
J'ajouterai également une version du redimensionnement qui maintient le rapport d'aspect fixe. Dans ce cas, il ajustera la hauteur pour correspondre à la largeur de la nouvelle image, en fonction du rapport hauteur / largeur initial, asp_rat , qui est float (!). Mais, pour ajuster la largeur à la hauteur, à la place, il vous suffit de commenter une ligne et de décommenter l'autre dans l' autre boucle . Vous verrez où.
Vous n'avez pas besoin des points-virgules (;), je les garde juste pour me rappeler la syntaxe des langages que j'utilise le plus souvent.
from PIL import Image
img_path = "filename.png";
img = Image.open(img_path); # puts our image to the buffer of the PIL.Image object
width, height = img.size;
asp_rat = width/height;
# Enter new width (in pixels)
new_width = 50;
# Enter new height (in pixels)
new_height = 54;
new_rat = new_width/new_height;
if (new_rat == asp_rat):
img = img.resize((new_width, new_height), Image.ANTIALIAS);
# adjusts the height to match the width
# NOTE: if you want to adjust the width to the height, instead ->
# uncomment the second line (new_width) and comment the first one (new_height)
else:
new_height = round(new_width / asp_rat);
#new_width = round(new_height * asp_rat);
img = img.resize((new_width, new_height), Image.ANTIALIAS);
# usage: resize((x,y), resample)
# resample filter -> PIL.Image.BILINEAR, PIL.Image.NEAREST (default), PIL.Image.BICUBIC, etc..
# https://pillow.readthedocs.io/en/3.1.x/reference/Image.html#PIL.Image.Image.resize
# Enter the name under which you would like to save the new image
img.save("outputname.png");
Et c'est fait. J'ai essayé de le documenter autant que possible, donc c'est clair.
J'espère que cela pourrait être utile à quelqu'un là-bas!
Ouvrez votre fichier image
from PIL import Image
im = Image.open("image.png")
Utilisez la méthode PIL Image.resize (size, resample = 0) , où vous remplacez (largeur, hauteur) de votre image par la taille 2-tuple.
Cela affichera votre image à sa taille d'origine:
display(im.resize((int(im.size[0]),int(im.size[1])), 0) )
Cela affichera votre image à la moitié de la taille:
display(im.resize((int(im.size[0]/2),int(im.size[1]/2)), 0) )
Cela affichera votre image au 1/3 de la taille:
display(im.resize((int(im.size[0]/3),int(im.size[1]/3)), 0) )
Cela affichera votre image à 1/4 de la taille:
display(im.resize((int(im.size[0]/4),int(im.size[1]/4)), 0) )
etc
display()
et où est-il situé?
from PIL import Image
from resizeimage import resizeimage
def resize_file(in_file, out_file, size):
with open(in_file) as fd:
image = resizeimage.resize_thumbnail(Image.open(fd), size)
image.save(out_file)
image.close()
resize_file('foo.tif', 'foo_small.jpg', (256, 256))
Vous pouvez redimensionner l'image par le code ci-dessous:
From PIL import Image
img=Image.open('Filename.jpg') # paste image in python folder
print(img.size())
new_img=img.resize((400,400))
new_img.save('new_filename.jpg')