Existe uma maneira óbvia de fazer isso que estou perdendo? Eu só estou tentando fazer miniaturas.
Existe uma maneira óbvia de fazer isso que estou perdendo? Eu só estou tentando fazer miniaturas.
Respostas:
Defina um tamanho máximo. Em seguida, calcule uma taxa de redimensionamento usando min(maxwidth/width, maxheight/height)
.
O tamanho adequado é oldsize*ratio
.
Obviamente, também existe um método de biblioteca para fazer isso: o método Image.thumbnail
.
Abaixo está um exemplo (editado) da documentação do 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)
? (isso é para divisão de ponto flutuante :)
ANTIALIAS
não é mais preferido para os usuários do popular travesseiro de forquilha da PIL. pillow.readthedocs.org/pt/3.0.x/releasenotes/…
thumbnail
só funciona se a imagem resultante for menor que a original. Por isso, acho que usar resize
é o melhor caminho.
Esse script 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 porcentagem de 300 pixels da largura original (img.size [0]) e multiplicando a altura original (img.size [1]) por essa porcentagem. Altere "largura da base" para qualquer outro número para alterar a largura padrão das 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')
sompic.jpg
. Por que isso acontece? Estou usando o Python 3.x
.jpeg
, use img.save('sompic.jpg', 'JPEG')
.
PIL.Image.ANTIALIAS
opção para resize
, realmente deve ser PIL.Image.LANCZOS
, embora sejam ambos 1
em valor, ver pillow.readthedocs.io/en/3.1.x/reference/...
Também recomendo usar o método de miniatura do PIL, porque ele remove todos os aborrecimentos da proporção.
Uma dica importante, no entanto: Substitua
im.thumbnail(size)
com
im.thumbnail(size,Image.ANTIALIAS)
por padrão, o PIL usa o filtro Image.NEAREST para redimensionar o que resulta em bom desempenho, mas baixa qualidade.
Image.thumbnail
.
Baseado em @tomvon, terminei de usar o seguinte (escolha seu caso):
a) Redimensionando a altura ( conheço a nova largura, preciso da nova altura )
new_width = 680
new_height = new_width * height / width
b) Redimensionando a largura ( eu conheço a nova altura, então preciso da nova largura )
new_height = 680
new_width = new_height * width / height
Então apenas:
img = img.resize((new_width, new_height), Image.ANTIALIAS)
resize
chamada, você está usando o new_width
para altura e largura?
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 você está tentando manter a mesma proporção, não redimensiona uma 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
Atualizando esta pergunta com um invólucro mais moderno. Esta biblioteca envolve o Pillow (um garfo do PIL) https://pypi.org/project/python-resize-image/
Permitindo que você faça 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()
Amontoa mais exemplos no link acima.
Eu estava tentando redimensionar algumas imagens para um vídeo de apresentação de slides e, por isso, queria não apenas uma dimensão máxima, mas uma largura e uma altura máximas (o tamanho do quadro do vídeo).
E sempre havia a possibilidade de um vídeo em retrato ...
O Image.thumbnail
método era promissor, mas não consegui torná-lo melhor para uma imagem menor.
Então, depois que não consegui encontrar uma maneira óbvia de fazer isso aqui (ou em outros lugares), escrevi esta função e a coloquei aqui para as seguintes:
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)
Um método simples para manter relações restritas e passar uma largura / altura máximas. Não é a mais bonita, mas realiza o trabalho 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 script python que usa essa função para executar o redimensionamento de imagens em lote.
Atualizou a resposta acima por "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')
Meu exemplo feio.
A função obtém um arquivo como: "pic [0-9a-z]. [Extension]", redimensiona-o para 120x120, move a seção para o centro e salva em "ico [0-9a-z]. [Extension]", 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:])
Eu redimensiono a imagem dessa maneira 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)
Também adicionarei uma versão do redimensionamento que mantém a proporção fixa. Nesse caso, ele ajustará a altura para corresponder à largura da nova imagem, com base na proporção inicial, asp_rat , que é flutuante (!). Mas, para ajustar a largura à altura, basta comentar uma linha e descomentar a outra no loop else . Você verá onde.
Você não precisa de ponto e vírgula (;), guardo-os apenas para me lembrar da sintaxe dos idiomas que utilizo com mais frequência.
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 está feito. Tentei documentá-lo o máximo possível, para que fique claro.
Espero que possa ser útil para alguém lá fora!
Abra seu arquivo de imagem
from PIL import Image
im = Image.open("image.png")
Use o método PIL Image.resize (tamanho, resample = 0) , onde você substitui (largura, altura) da sua imagem pelo tamanho 2-tupla.
Isso exibirá sua imagem no tamanho original:
display(im.resize((int(im.size[0]),int(im.size[1])), 0) )
Isso exibirá sua imagem com metade do tamanho:
display(im.resize((int(im.size[0]/2),int(im.size[1]/2)), 0) )
Isso exibirá sua imagem em 1/3 do tamanho:
display(im.resize((int(im.size[0]/3),int(im.size[1]/3)), 0) )
Isso exibirá sua imagem em 1/4 do tamanho:
display(im.resize((int(im.size[0]/4),int(im.size[1]/4)), 0) )
etc etc
display()
e onde está localizado?
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))
Você pode redimensionar a imagem pelo código abaixo:
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')