C'è un modo ovvio per farlo che mi manca? Sto solo cercando di creare miniature.
C'è un modo ovvio per farlo che mi manca? Sto solo cercando di creare miniature.
Risposte:
Definire una dimensione massima. Quindi, calcola un rapporto di ridimensionamento prendendo min(maxwidth/width, maxheight/height)
.
La dimensione corretta è oldsize*ratio
.
Esiste ovviamente anche un metodo di libreria per fare questo: il metodo Image.thumbnail
.
Di seguito è riportato un esempio (modificato) dalla documentazione 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)
? (Questo è per la divisione in virgola mobile però :)
ANTIALIAS
non è più preferito per gli utenti della famosa forcella Pillow di PIL. pillow.readthedocs.org/en/3.0.x/releasenotes/…
thumbnail
funziona solo se l'immagine risultante è più piccola di quella originale. Per questo immagino che usare resize
sia il modo migliore.
Questo script ridimensionerà un'immagine (somepic.jpg) usando PIL (Python Imaging Library) su una larghezza di 300 pixel e un'altezza proporzionale alla nuova larghezza. Lo fa determinando quale percentuale di 300 pixel è della larghezza originale (img.size [0]) e quindi moltiplicando l'altezza originale (img.size [1]) per quella percentuale. Cambia "basewidth" con qualsiasi altro numero per cambiare la larghezza predefinita delle tue immagini.
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
. Perché succede? Sto usando Python 3.x
.jpeg
, usa img.save('sompic.jpg', 'JPEG')
.
PIL.Image.ANTIALIAS
opzione per resize
, in realtà dovrebbe esserlo PIL.Image.LANCZOS
, sebbene siano entrambi 1
di valore, vedi pillow.readthedocs.io/en/3.1.x/reference/…
Consiglio anche di utilizzare il metodo delle miniature PIL, perché rimuove tutti i fastidi del rapporto da te.
Un suggerimento importante, però: sostituire
im.thumbnail(size)
con
im.thumbnail(size,Image.ANTIALIAS)
per impostazione predefinita, PIL utilizza il filtro Image.NEAREST per il ridimensionamento, il che si traduce in buone prestazioni, ma scarsa qualità.
Image.thumbnail
.
Basato su @tomvon, ho finito di usare il seguente (scegli il tuo caso):
a) Altezza di ridimensionamento ( conosco la nuova larghezza, quindi ho bisogno della nuova altezza )
new_width = 680
new_height = new_width * height / width
b) Ridimensionare la larghezza ( conosco la nuova altezza, quindi ho bisogno della nuova larghezza )
new_height = 680
new_width = new_height * width / height
Quindi solo:
img = img.resize((new_width, new_height), Image.ANTIALIAS)
resize
chiamata, stai usando new_width
sia per altezza che per larghezza?
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
Se stai cercando di mantenere le stesse proporzioni, non ridimensioneresti di una percentuale delle dimensioni originali?
Ad esempio, metà delle dimensioni originali
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))
Uso questa libreria:
pip install python-resize-image
Basta aggiornare questa domanda con un wrapper più moderno Questa libreria avvolge Pillow (una forcella di PIL) https://pypi.org/project/python-resize-image/
Ti permette di fare qualcosa del genere: -
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()
Moltissimi altri esempi nel link sopra.
Stavo cercando di ridimensionare alcune immagini per un video di presentazione e per questo motivo non volevo solo una dimensione massima, ma una larghezza massima e un'altezza massima (le dimensioni del fotogramma video).
E c'era sempre la possibilità di un video ritratto ...
IlImage.thumbnail
metodo era promettente, ma non sono riuscito a renderlo di lusso un'immagine più piccola.
Quindi dopo che non sono riuscito a trovare un modo ovvio per farlo qui (o in altri luoghi), ho scritto questa funzione e l'ho messa qui per quelli che verranno:
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)
Un metodo semplice per mantenere rapporti vincolati e passare una larghezza / altezza massima. Non è il più bello, ma fa il lavoro ed è facile da capire:
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
Ecco uno script Python che utilizza questa funzione per eseguire il ridimensionamento dell'immagine in batch.
Ho aggiornato la risposta sopra con "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')
Il mio brutto esempio.
La funzione ottiene il file come: "pic [0-9a-z]. [Extension]", ridimensionali a 120x120, sposta la sezione al centro e salva in "ico [0-9a-z]. [Extension]", funziona con il ritratto e paesaggio:
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:])
Ho ridimensionato l'immagine in questo modo e funziona molto bene
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)
Aggiungerò anche una versione del ridimensionamento che mantiene fisse le proporzioni. In questo caso, regolerà l'altezza in modo che corrisponda alla larghezza della nuova immagine, in base alle proporzioni iniziali, asp_rat , che è float (!). Tuttavia, per regolare la larghezza all'altezza, devi solo commentare una riga e rimuovere il commento dall'altra nel ciclo else . Vedrai dove.
Non hai bisogno dei punti e virgola (;), li tengo solo per ricordare a me stesso la sintassi delle lingue che uso più spesso.
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");
E fatto. Ho provato a documentarlo il più possibile, quindi è chiaro.
Spero possa essere utile a qualcuno là fuori!
Apri il tuo file immagine
from PIL import Image
im = Image.open("image.png")
Usa il metodo PIL Image.resize (size, resample = 0) , dove sostituisci (larghezza, altezza) della tua immagine con la dimensione di 2 tuple.
Questo visualizzerà la tua immagine nella dimensione originale:
display(im.resize((int(im.size[0]),int(im.size[1])), 0) )
Questo visualizzerà la tua immagine a 1/2 della dimensione:
display(im.resize((int(im.size[0]/2),int(im.size[1]/2)), 0) )
Questo visualizzerà la tua immagine a 1/3 della dimensione:
display(im.resize((int(im.size[0]/3),int(im.size[1]/3)), 0) )
Questo visualizzerà la tua immagine a 1/4 della dimensione:
display(im.resize((int(im.size[0]/4),int(im.size[1]/4)), 0) )
ecc ecc
display()
e dove si trova?
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))
Puoi ridimensionare l'immagine con il codice seguente:
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')