मैं पीआईएल का उपयोग करके एक छवि का आकार कैसे बदल सकता हूं और इसके पहलू अनुपात को बनाए रख सकता हूं?


437

क्या ऐसा करने का कोई स्पष्ट तरीका है जो मुझे याद आ रहा है? मैं केवल थंबनेल बनाने की कोशिश कर रहा हूं।


9
चूँकि यह प्रश्न काफी पुराना है, लेकिन उपयोगी है, और तकिया को अधिक पसंद किया जाता है, क्योंकि तकिया-आधारित ट्यूटोरियल इस पर एक नज़र डालते हैं
Wtower

3
मैंने छवियों के आकार के लिए एक छोटी सी लाइब्रेरी बनाई है, यह किसी भी मदद की हो सकती है: github.com/charlesthk/python-resize-image
Charlesthk

पीआईएल का अंतिम विमोचन 2006 में हुआ था। तकिए के बदलने की बात है कि मैं जानता हूं। पिलो की नवीनतम रिलीज़ 2 अप्रैल, 2020 थी।
डेविड मेडिनेट्स

जवाबों:


477

एक अधिकतम आकार को परिभाषित करें। फिर, आकार बदलने का अनुपात लें min(maxwidth/width, maxheight/height)

उचित आकार है oldsize*ratio

ऐसा करने के लिए निश्चित रूप से एक पुस्तकालय विधि भी है: विधि Image.thumbnail
नीचे पीआईएल प्रलेखन से एक (संपादित) उदाहरण है ।

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

4
जैसा कि यह कहता है, उदाहरण पायलट प्रलेखन से था, और वह उदाहरण (अभी भी) एंटीलियास ध्वज का उपयोग नहीं करता है। चूंकि यह संभवत: ज्यादातर लोग चाहते हैं, हालांकि, मैंने इसे जोड़ा।
gnud

3
पीआईएल नई छवि की ऊंचाई को दिए गए आकार (यहां 128) पर सेट करता है और पहलू अनुपात रखने के लिए चौड़ाई की गणना करता है। क्या ऊंचाई के बजाय चौड़ाई तय करने का कोई तरीका है? शायद मैं इसे अलग प्रश्न में पूछूंगा।
यूजीन

6
@ यूजीन: कुछ ऐसा करने की कोशिश s= img.size(); ratio = MAXWIDTH/s[0]; newimg = img.resize((s[0]*ratio, s[1]*ratio), Image.ANTIALIAS)? (यह फ़्लोटिंग पॉइंट डिवीज़न के लिए है :)
gnud

48
ध्यान दें कि ANTIALIASअब PIL के लोकप्रिय तकिया कांटे के उपयोगकर्ताओं के लिए पसंदीदा नहीं है। तकिया.readthedocs.org/en/3.0.x/releasenotes/…
जोशमेकर

8
पीआईएल के लिए पायथन 3 प्रलेखन कहता है कि thumbnailकेवल तभी काम करता है जब परिणामस्वरूप छवि मूल एक से छोटी हो। उसकी वजह से मुझे लगता है कि उपयोग resizeकरना बेहतर तरीका है।
तो S

253

यह स्क्रिप्ट PIL (पायथन इमेजिंग लाइब्रेरी) का उपयोग करके एक छवि (somepic.jpg) का आकार 300 पिक्सेल की चौड़ाई और नई चौड़ाई के अनुपात में होगी। यह निर्धारित करता है कि 300 प्रतिशत मूल चौड़ाई (img.size [0]) का प्रतिशत क्या है और फिर उस प्रतिशत से मूल ऊंचाई (img.size [1]) को गुणा करना है। अपनी छवियों की डिफ़ॉल्ट चौड़ाई को बदलने के लिए किसी अन्य नंबर पर "बेस्विथ" बदलें।

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

2
यदि आप एक बाहरी विधि के रूप में ज़ोप में इस स्क्रिप्ट का उपयोग कर रहे हैं, तो आपको ज़ोप के "छवि" के साथ नाम स्थान की गड़बड़ी से बचने के लिए "पीआईएल आयात छवि से" लाइन की आवश्यकता होगी।
टोमवॉँ

इस कोड से मुझे 0 बाइट आउटपुट फ़ाइल मिलती है sompic.jpg। ऐसा क्यों होता है? मैं पायथन 3.x का उपयोग कर रहा हूं
imrek

- अपडेट: पायथन 2.7 में ऐसा ही होता है।
imrek

मुझे पता चल गया होगा। यदि आप एक बचत कर रहे हैं .jpeg, का उपयोग करें img.save('sompic.jpg', 'JPEG')
imrek

5
नाइट: इसके लिए कोई PIL.Image.ANTIALIASविकल्प नहीं है resize, वास्तव में होना चाहिए PIL.Image.LANCZOS, हालांकि वे दोनों 1मूल्य में हैं, तकिए को
फ्रेड वू

66

मैं पीआईएल के थंबनेल विधि का उपयोग करने की भी सलाह देता हूं, क्योंकि यह आप से सभी अनुपात की परेशानियों को दूर करता है।

एक महत्वपूर्ण संकेत, हालांकि: बदलें

im.thumbnail(size)

साथ में

im.thumbnail(size,Image.ANTIALIAS)

डिफ़ॉल्ट रूप से, PIL, जो अच्छा प्रदर्शन करता है, लेकिन खराब गुणवत्ता के परिणाम के लिए Image.NEAREST फ़िल्टर का उपयोग करता है।


2
इसके साथ, आप केवल एक छवि का आकार घटा सकते हैं। इसके साथ आकार बढ़ाना संभव नहीं है Image.thumbnail
बर्न

45

@Tomvon में आधारित, मैंने निम्नलिखित का उपयोग करके समाप्त किया (अपना मामला चुनें):

क) आकार का आकार ( मुझे नई चौड़ाई पता है, इसलिए मुझे नई ऊंचाई की आवश्यकता है )

new_width  = 680
new_height = new_width * height / width 

b) चौड़ाई का आकार बदलना ( मुझे नई ऊंचाई पता है, इसलिए मुझे नई चौड़ाई की आवश्यकता है )

new_height = 680
new_width  = new_height * width / height

फिर बस:

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

6
आपके चर सभी मिश्रित हैं। आपकी पोस्ट चौड़ाई का आकार बदलते हुए कहती है, और फिर ऊँचाई का आकार बदल देती है। और resizeकॉल में, आप new_widthऊंचाई और चौड़ाई दोनों के लिए उपयोग कर रहे हैं ?
जछफर

उस @Zachafer के लिए एक निश्चित सुझाव
मो बेगी

1
बेहतर उन्हें पूर्णांक में परिवर्तित करें
ब्लैक थंडर

18

पीआईएल में पहले से ही एक छवि को क्रॉप करने का विकल्प है

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

20
यह सिर्फ छवि को क्रॉप करता है, यह पहलू अनुपात को बनाए नहीं रखता है।
रादु

2
यह किसी भी तरह से सवाल का जवाब नहीं देता है।
एएमसी

15
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

8
यह स्रोत छवि का पहलू अनुपात नहीं रखता है। यह छवि को 200x300 के लिए मजबूर करता है और परिणामस्वरूप निचोड़ा हुआ या फैला हुआ छवि होगा।
बर्न

यह किसी भी तरह से सवाल का जवाब नहीं देता है।
एएमसी

12

यदि आप उसी पहलू अनुपात को बनाए रखने की कोशिश कर रहे हैं, तो क्या आप मूल आकार के कुछ प्रतिशत का आकार परिवर्तन नहीं करेंगे?

उदाहरण के लिए, आधा मूल आकार

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

13
यह हो सकता है कि छवियां अलग-अलग आकार की थीं और परिणाम का आकार एक समान आकार का होना आवश्यक था
Steen

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

मैं इस पुस्तकालय का उपयोग करता हूं:

pip install python-resize-image

7

यदि आप पिलो के साथ छवि नहीं खोलना चाहते / नहीं चाहते हैं, तो इसका उपयोग करें:

from PIL import Image

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

4

इस प्रश्न को और अधिक आधुनिक आवरण के साथ अपडेट करते हुए यह पुस्तकालय पिलो (पीआईएल का एक कांटा) लपेटता है https://pypi.org/project/python-resize-image/

आपको ऐसा कुछ करने की अनुमति: -

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

उपरोक्त लिंक में अधिक उदाहरणों को छिपाता है।


3
resize_contain वास्तव में काफी उपयोगी लगता है!
Anytoe

4

मैं एक स्लाइड शो वीडियो के लिए कुछ छवियों का आकार बदलने की कोशिश कर रहा था और उसके कारण, मैं न केवल एक अधिकतम आयाम चाहता था, बल्कि एक अधिकतम चौड़ाई और एक अधिकतम ऊंचाई (वीडियो फ्रेम का आकार)।
और हमेशा एक पोर्ट्रेट वीडियो की संभावना थी ...
Image.thumbnail विधि का वादा किया गया था, लेकिन मैं इसे upscale एक छोटी छवि नहीं बना सके।

इसलिए जब मुझे ऐसा करने का कोई स्पष्ट तरीका नहीं मिला, तो यहां (या कुछ अन्य स्थानों पर), मैंने इस समारोह को लिखा और आने वाले लोगों के लिए इसे यहां रखा:

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)

3

विवश अनुपात रखने और अधिकतम चौड़ाई / ऊँचाई को पार करने की एक सरल विधि। सबसे सुंदर नहीं है लेकिन काम हो जाता है और समझने में आसान होता है:

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

यहाँ एक पायथन लिपि है जो बैच इमेज को आकार देने के लिए इस फ़ंक्शन का उपयोग करती है।


3

"टॉमवॉन" द्वारा ऊपर दिए गए उत्तर को अपडेट किया है

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

एक आकर्षण की तरह काम! इसलिए धन्यवाद!
डेनिस सवेंको

2

मेरा बदसूरत उदाहरण।

फ़ंक्शन को फ़ाइल मिलती है: "pic [0-9a-z]। [एक्सटेंशन]", उन्हें 120x120 का आकार दें, अनुभाग को केंद्र में ले जाएं और "ico [0-9a-z] [save] [एक्सटेंशन] में सेव करें, चित्र के साथ काम करता है। और परिदृश्य:

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

2

मैंने इस तरह से छवि का आकार बदला और यह बहुत अच्छा काम कर रहा है

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)

2

मैं आकार का एक संस्करण भी जोड़ूंगा जो पहलू अनुपात को ठीक रखता है। इस मामले में, यह प्रारंभिक पहलू अनुपात, एस्पर्ट , जो फ्लोट (!) के आधार पर, नई छवि की चौड़ाई से मेल खाने के लिए ऊंचाई को समायोजित करेगा । लेकिन, ऊंचाई के लिए चौड़ाई समायोजित करने के बजाय, आप बस में एक लाइन और टिप्पणी हटाएं अन्य टिप्पणी देना चाहते हैं और कुछ पाश। आप देखेंगे, कहाँ।

आपको अर्धविराम (;) की आवश्यकता नहीं है, मैं उन्हें केवल उन भाषाओं की वाक्य रचना की याद दिलाने के लिए रखता हूं जिनका मैं अधिक बार उपयोग करता हूं।

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

और हो गया। मैंने इसे जितना संभव हो उतना दस्तावेज़ करने की कोशिश की, इसलिए यह स्पष्ट है।

मुझे आशा है कि यह किसी के लिए उपयोगी हो सकता है वहाँ!


0

अपनी छवि फ़ाइल खोलें

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

PIL Image.resize (आकार, resample = 0) विधि का उपयोग करें , जहाँ आप अपनी छवि के आकार (चौड़ाई, ऊँचाई) को 2-ट्यूपल के लिए प्रतिस्थापित करते हैं।

यह आपकी छवि को मूल आकार में प्रदर्शित करेगा:

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

यह आपकी छवि को 1/2 आकार में प्रदर्शित करेगा:

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

यह आपकी छवि को 1/3 आकार में प्रदर्शित करेगा:

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

यह आपकी छवि को 1/4 आकार में प्रदर्शित करेगा:

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

आदि आदि


क्या है display()और यह कहाँ स्थित है?
एंथनी

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

-1

आप नीचे दिए गए कोड द्वारा छवि का आकार बदल सकते हैं:

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')
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.