كيف يمكنني تغيير حجم الصورة باستخدام PIL والحفاظ على نسبة جانبها؟

StackOverflow https://stackoverflow.com/questions/273946

سؤال

هل هناك طريقة واضحة للقيام بذلك أن أنا في عداد المفقودين؟ أنا مجرد محاولة لجعل الصور المصغرة.

هل كانت مفيدة؟

المحلول

وتحديد الحد الأقصى لحجم. ثم، حساب نسبة تغيير الحجم من خلال اتخاذ min(maxwidth/width, maxheight/height).

وحجم الصحيح هو oldsize*ratio.

وهناك بالطبع أيضا وسيلة مكتبة للقيام بذلك: في Image.thumbnail طريقة
وفيما يلي (تحرير) مثال من الوثائق 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

نصائح أخرى

وهذا السيناريو سوف تغيير حجم صورة (somepic.jpg) باستخدام PIL (مكتبة التصوير بيثون) إلى عرض 300 بكسل وارتفاع يتناسب مع العرض الجديد. وذلك من خلال تحديد النسبة المئوية 300 بكسل للعرض الأصلي (img.size [0])، ثم ضرب الارتفاع الأصلي (img.size [1]) من خلال هذه النسبة. التغيير "basewidth" إلى أي رقم آخر لتغيير العرض الافتراضي من الصور الخاصة بك.

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

وأوصي أيضا باستخدام طريقة مصغرة PIL، لأن ذلك يزيل كل متاعب نسبة منك.

وتلميح واحد مهم، على الرغم من: استبدال

im.thumbnail(size)

مع

im.thumbnail(size,Image.ANTIALIAS)

وبشكل افتراضي، يستخدم PIL مرشح Image.NEAREST لتغيير حجم مما يؤدي إلى أداء جيد، ولكن سوء نوعية.

ومقرها فيtomvon، I الانتهاء من استخدام ما يلي:

وتغيير حجم العرض:

new_width  = 680
new_height = new_width * height / width 

وتغيير حجم الارتفاع:

new_height = 680
new_width  = new_height * width / height

وبعد ذلك فقط:

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

وPIL بالفعل الخيار لاقتصاص صورة

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

إذا كنت تحاول الحفاظ على نفس نسبة الارتفاع، ثم لن تغيير حجم بعض نسبة مئوية من الحجم الأصلي؟

وعلى سبيل المثال، نصف الحجم الأصلي

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

وأنا استخدم هذه المكتبة:

pip install python-resize-image

وبلدي سبيل المثال القبيح.

وظيفة الحصول على ملف مثل: "الموافقة المسبقة عن علم [0-9a زي] [إضافة]"، حجمها إلى 120x120، قسم ينتقل إلى مركز وحفظ إلى "منظمة البن الدولية [0-9a زي] [إضافة]". يعمل مع صورة والمناظر الطبيعية:

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

وهناك طريقة بسيطة للحفاظ على نسب مقيدة وتمرير عرض ماكس / الارتفاع. ليس أجمل ولكن يحصل على هذه المهمة ومن السهل أن نفهم:

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

وفيما يلي الثعبان النصي يستخدم هذه الوظيفة لتشغيل الصور دفعة تغيير الحجم.

وكنت أحاول أن تغيير بعض الصور لشريط فيديو عرض الشرائح وبسبب ذلك، أردت ليس فقط كحد أقصى واحد البعد، ولكن عرض ماكس <م> و ارتفاع ماكس (حجم إطار الفيديو) .
وكان هناك دائما إمكانية فيديو صورة ...
كانت الطريقة Image.thumbnail اعدة، ولكن أنا لا يمكن أن تجعل الراقي صورة أصغر.

وهكذا بعد أن لم يتمكن من العثور على طريقة واضحة لنفعل ذلك هنا (أو في بعض الأماكن الأخرى)، كتبت هذه الوظيفة وضعه هنا لتلك القادمة:

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)

إذا كنت لا تريد / لا يكون هناك حاجة لفتح صورة مع وسادة، واستخدام هذه:

from PIL import Image

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

وأنا resizeed الصورة في مثل هذه الطريقة وانها تعمل بشكل جيد جدا

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)

ومجرد تحديث هذا السؤال مع المجمع أكثر حداثة هذه المكتبة يلتف سادة (مفترق PIL) 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()

وأكوام من الأمثلة في الرابط أعلاه.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top