Pergunta

Existe uma maneira óbvia de fazer isso que eu estou perdendo? Eu só estou tentando fazer miniaturas.

Foi útil?

Solução

Defina um tamanho máximo. Em seguida, calcular uma escala de redimensionamento tomando min(maxwidth/width, maxheight/height).

O tamanho adequado é oldsize*ratio.

Há, naturalmente, também um método de biblioteca para fazer isso:. A Image.thumbnail método
Abaixo está um (editado) exemplo do PIL documentação .

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

Outras dicas

Este script irá redimensionar uma imagem (somepic.jpg) usando PIL (Python Imaging Library) para uma largura de 300 pixels e uma altura proporcional à nova largura. Ele faz isso determinando qual a percentagem 300 pixels é de largura original (img.size [0]) e, em seguida, multiplicando a altura original (img.size [1]) por esta percentagem. Change "basewidth" para qualquer outro número para alterar a largura padrão de suas imagens.

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

Eu também recomendo utilizando o método de miniaturas do PIL, porque remove todas as dificuldades razão de você.

Uma dica importante, porém: Substitua

im.thumbnail(size)

com

im.thumbnail(size,Image.ANTIALIAS)

por padrão, PIL usa o filtro Image.NEAREST para redimensionamento que resulta em um bom desempenho, mas de má qualidade.

Com base em @tomvon, eu terminar de usar o seguinte:

O redimensionamento width:

new_width  = 680
new_height = new_width * height / width 

altura redimensionamento:

new_height = 680
new_width  = new_height * width / height

Em seguida, basta:

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

PIL já tem a opção de cortar uma imagem

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

Se você está tentando manter a mesma proporção, então você não iria redimensionar por alguma porcentagem do tamanho original?

Por exemplo, metade do tamanho 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))

Eu uso esta biblioteca:

pip install python-resize-image

Meu exemplo feio.

Função arquivo get como: "pic [0-9a-z] [extensão].", Redimensioná-las para 120x120, seção move para o centro e salvar para "ico [0-9a-z] [extensão].", trabalha com retrato e paisagem:

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

Um método simples para manter relações restritas e passando um máximo largura / altura. Não o mais bonito, mas começa o trabalho feito e é 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

Aqui está um python roteiro que usa essa função para executar o redimensionamento da imagem do grupo.

Eu estava tentando redimensionar algumas imagens para um vídeo slideshow e por causa disso, eu queria não apenas uma dimensão máxima, mas uma largura máxima e a altura máxima (o tamanho do quadro de vídeo) .
E havia sempre a possibilidade de um vídeo retrato ...
O método Image.thumbnail estava prometendo, mas eu não poderia fazê-lo upscale uma imagem menor.

Então, depois eu não conseguia encontrar uma maneira óbvia de fazer isso aqui (ou em alguns outros lugares), eu escrevi essa função e colocá-lo aqui para os vir:

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)

Se você não quer / não tenho uma necessidade para a imagem aberta com Pillow, use o seguinte:

from PIL import Image

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

Eu resizeed a imagem de tal maneira uma e está funcionando muito bem

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)

Apenas atualizando esta pergunta com um invólucro mais moderno Esta biblioteca envolve Pillow (um fork do PIL) https://pypi.org/project/python-resize-image/

O que lhe permite fazer algo assim: -

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

Heaps mais exemplos no link acima.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top