Wie ändere ich die Größe eines Bildes PIL verwendet und das Seitenverhältnis beibehalten?
-
07-07-2019 - |
Frage
Gibt es eine offensichtliche Möglichkeit, dies zu tun, dass ich fehle? Ich versuche nur, um Thumbnails zu machen.
Lösung
Definieren Sie eine maximale Größe.
Dann berechnet ein Resize-Verhältnis von min(maxwidth/width, maxheight/height)
nehmen.
Die richtige Größe ist oldsize*ratio
.
Es gibt natürlich auch eine Bibliothek Methode, dies zu tun. Das Verfahren Image.thumbnail
Nachfolgend finden Sie eine (bearbeitete) Beispiel aus dem PIL Dokumentation .
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
Andere Tipps
Dieses Skript wird ein Bild (somepic.jpg) mit PIL (Python Imaging Library) auf eine Breite von 300 Pixeln und einer Höhe proportional zu der neuen Breite ändern. Es tut dies durch Bestimmung, welche Prozent 300 Pixel der ursprünglichen Breite (img.size [0]) und dann die ursprüngliche Höhe Multiplizieren (img.size [1]) um diesen Prozentsatz. Change „Basisbreite“ auf jede andere Zahl die Standardbreite der Bilder zu ändern.
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')
Ich empfehle auch PIL Thumbnail-Methode, weil es alle Verhältnis Ärger von Ihnen entfernt.
Ein wichtiger Hinweis, aber: Ersetzen Sie
im.thumbnail(size)
mit
im.thumbnail(size,Image.ANTIALIAS)
standardmäßig PIL die Image.NEAREST Filter zum Ändern der Größe verwendet, die zu einer guten Leistung führt, aber schlechte Qualität.
in @tomvon Basierend, beenden ich mit dem folgenden:
Ändern der Größe Breite:
new_width = 680
new_height = new_width * height / width
Ändern der Größe Höhe:
new_height = 680
new_width = new_height * width / height
Dann einfach:
img = img.resize((new_width, new_height), Image.ANTIALIAS)
PIL hat bereits die Möglichkeit, ein Bild zuzuschneiden
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
Wenn Sie versuchen, das gleiche Seitenverhältnis zu erhalten, dann würden Sie nicht von einem Prozentsatz der ursprünglichen Größe der Größe?
Zum Beispiel die Hälfte der ursprünglichen Größe
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))
Ich benutze diese Bibliothek:
pip install python-resize-image
Ihr hässliches Beispiel.
Funktion erhält Datei wie: "pic [0-9a-z] [Erweiterung]", die Größe, sie zu 120x120, bewegt Abschnitt zum Zentrum und zu retten "ico [0-9a-z] [Erweiterung]." arbeitet mit Hoch- und Querformat:
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:])
Eine einfache Methode zum beschränkten Verhältnissen zu halten und eine maximale Breite / Höhe verläuft. Nicht das schönste, aber bekommt den Job zu erledigen und ist leicht zu verstehen:
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
Hier ist ein Python-Skript dass diese Funktion verwendet Batch Bild Verkleinerung ausgeführt werden.
Ich hatte versucht, einige Bilder für ein Diashow Video, um die Größe und aus diesem Grunde wollte ich nicht nur eine max Dimension, sondern eine maximale Breite und eine maximale Höhe (die Größe des Videobildes) .
Und es gab immer die Möglichkeit, ein Porträt Video ...
Die Image.thumbnail
Methode war vielversprechend, aber ich konnte es nicht ein kleineres Bild gehobenen machen.
So, nachdem ich keine offensichtliche Art und Weise zu tun hier finden konnte, dass (oder an einigen anderen Orten), habe ich diese Funktion geschrieben und lege es hier für diejenigen zu kommen:
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)
Wenn Sie nicht / wollen haben keine Notwendigkeit, das Bild zu öffnen mit Kissen, verwenden Sie diese:
from PIL import Image
new_img_arr = numpy.array(Image.fromarray(img_arr).resize((new_width, new_height), Image.ANTIALIAS))
I resizeed das Bild so, und es funktioniert sehr gut
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)
Aktualisieren Sie einfach diese Frage mit einem moderneren Wrapper Diese Bibliothek wickelt Kissen (eine Gabel von PIL) https://pypi.org/project/python-resize-image/
So dass Sie so etwas wie dies zu tun: -
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 weitere Beispiele in dem obigen Link.