Hoe pas ik het formaat van een afbeelding aan met PIL en behoud ik de hoogte-breedteverhouding?

Is er een voor de hand liggende manier om dit te doen die ik mis? Ik probeer alleen thumbnails te maken.


Antwoord 1, autoriteit 100%

Definieer een maximale grootte.
Bereken vervolgens een formaatverhouding door min(maxwidth/width, maxheight/height)te nemen.

De juiste maat is oldsize*ratio.

Er is natuurlijk ook een bibliotheekmethode om dit te doen: de methode Image.thumbnail.
Hieronder staat een (bewerkt) voorbeeld uit de PIL-documentatie.

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

Antwoord 2, autoriteit 58%

Dit script wijzigt het formaat van een afbeelding (somepic.jpg) met behulp van PIL (Python Imaging Library) tot een breedte van 300 pixels en een hoogte die evenredig is met de nieuwe breedte. Het doet dit door te bepalen welk percentage 300 pixels van de oorspronkelijke breedte is (img.size[0]) en vervolgens de originele hoogte (img.size[1]) te vermenigvuldigen met dat percentage. Wijzig “basisbreedte” in een ander getal om de standaardbreedte van uw afbeeldingen te wijzigen.

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('somepic.jpg')

Antwoord 3, autoriteit 13%

Ik raad ook aan om de thumbnail-methode van PIL te gebruiken, omdat dit alle gedoe met verhoudingen uit handen neemt.

Eén belangrijke tip echter: Vervang

im.thumbnail(size)

met

im.thumbnail(size,Image.ANTIALIAS)

PIL gebruikt standaard het Image.NEAREST-filter voor het wijzigen van de grootte, wat resulteert in goede prestaties, maar slechte kwaliteit.


Antwoord 4, autoriteit 10%

Gebaseerd op @tomvon, heb ik het volgende gebruikt (kies je zaak):

a) Hoogte aanpassen(Ik ken de nieuwe breedte, dus ik heb de nieuwe hoogte nodig)

new_width  = 680
new_height = new_width * height / width 

b) Formaat van breedte wijzigen(Ik weet de nieuwe hoogte, dus ik heb de nieuwe breedte nodig)

new_height = 680
new_width  = new_height * width / height

Dan gewoon:

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

Antwoord 5, autoriteit 4%

Als u dezelfde beeldverhouding probeert te behouden, zou u het formaat dan niet met een bepaald percentage van het oorspronkelijke formaat aanpassen?

Bijvoorbeeld de helft van het originele formaat

half = 0.5
out = im.resize( [int(half * s) for s in im.size] )

Antwoord 6, autoriteit 3%

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

Antwoord 7, Autoriteit 2%

Pil heeft al de optie om een ​​afbeelding te bijsnijden

img = ImageOps.fit(img, size, Image.ANTIALIAS)

Antwoord 8

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

Ik gebruik deze bibliotheek:

pip install python-resize-image

Antwoord 9

Als u niet wilt / hoeft niet om de afbeelding met kussen te openen, gebruikt u dit:

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

Antwoord 10

gewoon deze vraag bijwerken met een moderner wrapper
Deze bibliotheek wikkelt kussen (een vork van pil)
https://pypi.org/project/python-resize-image/

zodat u zoiets wilt doen: –

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

HEALPEN MEERE VOORBEELDINGEN IN DE BOVENSTE LINK.


Antwoord 11

Ik probeerde een aantal afbeeldingen voor een diavoorstelling-video te wijzigen en daarom wilde ik niet alleen één Max-dimensie, maar een maximale breedte en een maximale hoogte (de grootte van het videoframe) .
En er was altijd de mogelijkheid van een portretvideo …
De Image.thumbnailMethode was veelbelovend, maar ik kon het niet luxueus maken van een kleiner beeld.

Dus nadat ik geen voor de hand liggende manier kon vinden om dat hier (of op een paar andere plaatsen) te doen, schreef ik deze functie en plaats het hier voor die komen:

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)

Antwoord 12

Open uw afbeeldingsbestand

from PIL import Image
im = Image.open("image.png")

Gebruik PIL Image.resize (size, resample=0) methode, waarbij je (breedte, hoogte) van je afbeelding vervangt door de maat 2-tuple.

Hiermee wordt uw afbeelding op het oorspronkelijke formaat weergegeven:

display(im.resize((int(im.size[0]),int(im.size[1])), 0) )

Hiermee wordt uw afbeelding weergegeven op de helft van de grootte:

display(im.resize((int(im.size[0]/2),int(im.size[1]/2)), 0) )

Hierdoor wordt uw afbeelding weergegeven op 1/3 van de grootte:

display(im.resize((int(im.size[0]/3),int(im.size[1]/3)), 0) )

Hierdoor wordt uw afbeelding weergegeven op 1/4 van de grootte:

display(im.resize((int(im.size[0]/4),int(im.size[1]/4)), 0) )

enz enz


Antwoord 13

Ik zal ook een versie van de formaatwijziging toevoegen die de beeldverhouding vasthoudt.
In dit geval wordt de hoogte aangepast aan de breedte van de nieuwe afbeelding, gebaseerd op de oorspronkelijke beeldverhouding, asp_rat, die float(!) is.
Maar om de breedte aan de hoogte aan te passen, hoeft u alleen maar commentaar te geven op de ene regel en de andere in de else-lus. Je zult zien waar.

Je hebt de puntkomma’s (;) niet nodig, ik bewaar ze alleen om mezelf te herinneren aan de syntaxis van talen die ik vaker gebruik.

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");

En het is klaar. Ik heb geprobeerd het zo goed mogelijk te documenteren, dus het is duidelijk.

Ik hoop dat het iemand kan helpen!


Antwoord 14

Een eenvoudige methode om beperkte verhoudingen te behouden en een maximale breedte/hoogte door te geven. Niet de mooiste, maar klaart de klus en is gemakkelijk te begrijpen:

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 is een python-scriptdat deze functie gebruikt om batchgrootte van afbeeldingen uit te voeren.


Antwoord 15

Heb het antwoord hierboven bijgewerkt door “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')

Antwoord 16

U kunt PIL’s Image.thumbnailmet sys.maxsizeals uw formaatlimiet is slechts op één dimensie (breedte of hoogte).

Als u bijvoorbeeld het formaat van een afbeelding wilt wijzigen zodat de hoogte niet meer dan 100 px is, terwijl u de beeldverhouding behoudt, kunt u zoiets als dit doen:

import sys
from PIL import Image
image.thumbnail([sys.maxsize, 100], Image.ANTIALIAS)

Houd er rekening mee dat Image.thumbnailhet formaat van de afbeelding op zijn plaats aanpast, wat anders is dan Image.resize, dat in plaats daarvan de aangepaste afbeelding retourneert zonder de oorspronkelijke afbeelding te wijzigen.


Antwoord 17

Mijn lelijke voorbeeld.

Functie bestand ophalen zoals: “pic[0-9a-z].[extensie]”, formaat wijzigen naar 120×120, sectie naar het midden verplaatsen en opslaan naar “ico[0-9a-z].[extensie]”, werkt met portret en landschap:

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

Antwoord 18

Ik heb de afbeelding op zo’n manier aangepast en het werkt heel goed

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)

Antwoord 19

Het volgende script maakt mooie miniaturen van alle JPEG-afbeeldingen met behoud van beeldverhoudingen met een maximale resolutie van 128×128.

from PIL import Image
img = Image.open("D:\\Pictures\\John.jpg")
img.thumbnail((680,680))
img.save("D:\\Pictures\\John_resize.jpg")

Antwoord 20

import cv2
from skimage import data 
import matplotlib.pyplot as plt
from skimage.util import img_as_ubyte
from skimage import io
filename='abc.png'
image=plt.imread(filename)
im=cv2.imread('abc.png')
print(im.shape)
im.resize(300,300)
print(im.shape)
plt.imshow(image)

Antwoord 21

Je kunt het formaat van de afbeelding wijzigen met onderstaande code:

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

Other episodes