reescalar - reducir tamaño de imagen python
¿Cómo redimensiono una imagen usando PIL y mantengo su relación de aspecto? (11)
¿Hay una manera obvia de hacer esto que me estoy perdiendo? Solo estoy tratando de hacer miniaturas.
Basado en @tomvon, terminé de usar lo siguiente:
Ancho de redimensionamiento:
new_width = 680
new_height = new_width * height / width
Altura de redimensionamiento:
new_height = 680
new_width = new_height * width / height
Entonces solo
img = img.resize((new_width, new_height), Image.ANTIALIAS)
Este script cambiará el tamaño de una imagen (somepic.jpg) usando PIL (Python Imaging Library) a un ancho de 300 píxeles y una altura proporcional al nuevo ancho. Lo hace determinando qué porcentaje de 300 píxeles tiene el ancho original (img.size [0]) y luego multiplicando la altura original (img.size [1]) por ese porcentaje. Cambie "basewidth" a cualquier otro número para cambiar el ancho predeterminado de sus imágenes.
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'')
Mi feo ejemplo.
La función obtiene el archivo como: "pic [0-9a-z]. [Extensión]", cambia su tamaño a 120x120, mueve la sección al centro y guarda a "ico [0-9a-z]. [Extensión]", funciona con el retrato y el paisaje:
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:])
PIL ya tiene la opción de recortar una imagen.
img = ImageOps.fit(img, size, Image.ANTIALIAS)
Si está tratando de mantener la misma relación de aspecto, ¿no cambiaría el tamaño en algún porcentaje del tamaño original?
Por ejemplo, la mitad del tamaño original.
half = 0.5
out = im.resize( [int(half * s) for s in im.size] )
Solo actualizando esta pregunta con un envoltorio más moderno Esta biblioteca envuelve la Almohada (una bifurcación de PIL) https://pypi.org/project/python-resize-image/
Permitiéndote hacer algo como esto:
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()
Montones de más ejemplos en el enlace de arriba.
También recomiendo usar el método de miniaturas de PIL, ya que elimina todos los problemas de relación de ti.
Una pista importante, sin embargo: reemplazar
im.thumbnail(size)
con
im.thumbnail(size,Image.ANTIALIAS)
de forma predeterminada, PIL utiliza el filtro Image.NEAREST para cambiar el tamaño, lo que da como resultado un buen rendimiento pero una calidad deficiente.
Un método simple para mantener relaciones restringidas y pasar una anchura / altura máxima. No es el más bonito, pero hace el trabajo y es fácil de entender:
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
Aquí hay un script de Python que utiliza esta función para ejecutar el cambio de tamaño de la imagen por lotes
Definir un tamaño máximo. Luego, calcule una relación de cambio de tamaño tomando min(maxwidth/width, maxheight/height)
.
El tamaño apropiado es de tamaño oldsize*ratio
.
Por supuesto, también hay un método de biblioteca para hacer esto: el método Image.thumbnail
.
A continuación se muestra un ejemplo (editado) de la documentación de 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
from PIL import Image
img = Image.open(''/your iamge 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 u want ,*.png,*jpg,*.gif
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))
Yo uso esta biblioteca:
pip install python-resize-image