Pregunta

¿Hay una forma obvia de hacer esto que me falta? Solo estoy tratando de hacer miniaturas.

¿Fue útil?

Solución

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

Otros consejos

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. Para ello, determina qué porcentaje de 300 píxeles es del ancho original (tamaño img. [0]) y luego multiplica la altura original (tamaño img. [1]) por ese porcentaje. Cambiar " ancho de base " 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') 

También recomiendo usar el método de miniaturas de PIL, porque elimina todas las molestias de la relación.

Sin embargo, una pista importante: 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 resulta en un buen rendimiento, pero de baja calidad.

Basado en @tomvon, terminé de usar lo siguiente:

Ancho de redimensionamiento:

new_width  = 680
new_height = new_width * height / width 

Altura de cambio de tamaño:

new_height = 680
new_width  = new_height * width / height

Entonces solo:

img = img.resize((new_width, new_height), Image.ANTIALIAS)

PIL ya tiene la opción de recortar una imagen

img = ImageOps.fit(img, size, Image.ANTIALIAS)
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

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

Mi ejemplo feo.

Función get file como: " pic [0-9a-z]. [extension] " ;, redimensionarlos a 120x120, mueve la sección al centro y guardar en " ico [0-9a-z]. [extension ] " ;, funciona con retrato y 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:])

Un método simple para mantener relaciones restringidas y pasar un ancho / alto máximo. 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.

Estaba tratando de cambiar el tamaño de algunas imágenes para un video de presentación de diapositivas y debido a eso, quería no solo una dimensión máxima, sino un ancho máximo y una altura máxima (el tamaño del cuadro de video) .
Y siempre existía la posibilidad de un video de retrato ...
El método Image.thumbnail fue prometedor, pero no pude mejorar la imagen más pequeña.

Entonces, después de que no pude encontrar una manera obvia de hacer eso aquí (o en otros lugares), escribí esta función y la puse aquí para los que vendrán:

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)

Si no desea / no necesita abrir una imagen con Pillow, use esto:

from PIL import Image

new_img_arr = numpy.array(Image.fromarray(img_arr).resize((new_width, new_height), Image.ANTIALIAS))

Cambié el tamaño de la imagen de tal manera y está funcionando muy 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)

Simplemente actualizo esta pregunta con un contenedor más moderno Esta biblioteca envuelve Pillow (un tenedor de PIL) https://pypi.org/project/python-resize-image/

Permitiéndole 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()

Apila más ejemplos en el enlace anterior.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top