如何使用PIL调整图像的大小并保持它的长宽比?

时间:2022-08-27 11:08:26

Is there an obvious way to do this that I'm missing? I'm just trying to make thumbnails.

有没有一种明显的方法可以让我忽略?我只是想做个缩略图。

11 个解决方案

#1


347  

Define a maximum size. Then, compute a resize ratio by taking min(maxwidth/width, maxheight/height).

定义一个最大尺寸。然后,通过取最小值(maxwidth/width, maxheight/height)来计算调整大小的比例。

The proper size is oldsize*ratio.

合适的尺寸是旧尺寸*比。

There is of course also a library method to do this: the method Image.thumbnail.
Below is an (edited) example from the PIL documentation.

当然,还有一个库方法可以做到这一点:方法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

#2


151  

This script will resize an image (somepic.jpg) using PIL (Python Imaging Library) to a width of 300 pixels and a height proportional to the new width. It does this by determining what percentage 300 pixels is of the original width (img.size[0]) and then multiplying the original height (img.size[1]) by that percentage. Change "basewidth" to any other number to change the default width of your images.

这个脚本将使用PIL (Python图像库)来调整一个图像(somepic.jpg),宽度为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') 

#3


48  

I also recommend using PIL's thumbnail method, because it removes all the ratio hassles from you.

我也推荐使用PIL's thumbnail方法,因为它可以消除您对比率的所有困扰。

One important hint, though: Replace

一个重要的提示是:替换

im.thumbnail(size)

with

im.thumbnail(size,Image.ANTIALIAS)

by default, PIL uses the Image.NEAREST filter for resizing which results in good performance, but poor quality.

默认情况下,PIL使用图像。用于调整大小的最近的过滤器,其结果是良好的性能,但质量较差。

#4


19  

Based in @tomvon, I finished using the following:

以@tomvon为原型,我完成了以下内容:

Resizing width:

调整宽度:

new_width  = 680
new_height = new_width * height / width 

Resizing height:

调整高度:

new_height = 680
new_width  = new_height * width / height

Then just:

然后:

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

#5


13  

PIL already has the option to crop an image

PIL已经有了裁剪图像的选项。

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

#6


10  

If you are trying to maintain the same aspect ratio, then wouldn't you resize by some percentage of the original size?

如果您试图保持相同的纵横比,那么您不需要调整原始大小的某个百分比吗?

For example, half the original size

例如,原尺寸的一半

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

#7


9  

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

#8


2  

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

I use this library:

我使用这个库:

pip install python-resize-image

#9


1  

My ugly example.

我的丑陋的例子。

Function get file like: "pic[0-9a-z].[extension]", resize them to 120x120, moves section to center and save to "ico[0-9a-z].[extension]", works with portrait and landscape:

函数get file like:“pic[0-9a-z]”。[扩展]",调整大小到120x120,移动部分到中心保存到"ico[0-9a-z]。[延伸]“,与肖像和景观一起工作:

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

#10


0  

Just updating this question with a more modern wrapper This library wraps Pillow (a fork of PIL) https://pypi.org/project/python-resize-image/

只需使用更现代的包装器更新这个问题,这个库就会包装Pillow (PIL的一个分支)https://pypi.org/project/python-resize-image/

Allowing you to do something like this :-

允许你做这样的事:-

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 more examples in the above link.

在上面的链接中有更多的例子。

#11


0  

A simple method for keeping constrained ratios and passing a max width / height. Not the prettiest but gets the job done and is easy to understand:

一种简单的保持约束比率和传递最大宽度/高度的方法。不是最漂亮的,但完成了工作,很容易理解:

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

Here's a python script that uses this function to run batch image resizing.

下面是一个python脚本,它使用这个函数运行批处理图像大小调整。

#1


347  

Define a maximum size. Then, compute a resize ratio by taking min(maxwidth/width, maxheight/height).

定义一个最大尺寸。然后,通过取最小值(maxwidth/width, maxheight/height)来计算调整大小的比例。

The proper size is oldsize*ratio.

合适的尺寸是旧尺寸*比。

There is of course also a library method to do this: the method Image.thumbnail.
Below is an (edited) example from the PIL documentation.

当然,还有一个库方法可以做到这一点:方法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

#2


151  

This script will resize an image (somepic.jpg) using PIL (Python Imaging Library) to a width of 300 pixels and a height proportional to the new width. It does this by determining what percentage 300 pixels is of the original width (img.size[0]) and then multiplying the original height (img.size[1]) by that percentage. Change "basewidth" to any other number to change the default width of your images.

这个脚本将使用PIL (Python图像库)来调整一个图像(somepic.jpg),宽度为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') 

#3


48  

I also recommend using PIL's thumbnail method, because it removes all the ratio hassles from you.

我也推荐使用PIL's thumbnail方法,因为它可以消除您对比率的所有困扰。

One important hint, though: Replace

一个重要的提示是:替换

im.thumbnail(size)

with

im.thumbnail(size,Image.ANTIALIAS)

by default, PIL uses the Image.NEAREST filter for resizing which results in good performance, but poor quality.

默认情况下,PIL使用图像。用于调整大小的最近的过滤器,其结果是良好的性能,但质量较差。

#4


19  

Based in @tomvon, I finished using the following:

以@tomvon为原型,我完成了以下内容:

Resizing width:

调整宽度:

new_width  = 680
new_height = new_width * height / width 

Resizing height:

调整高度:

new_height = 680
new_width  = new_height * width / height

Then just:

然后:

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

#5


13  

PIL already has the option to crop an image

PIL已经有了裁剪图像的选项。

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

#6


10  

If you are trying to maintain the same aspect ratio, then wouldn't you resize by some percentage of the original size?

如果您试图保持相同的纵横比,那么您不需要调整原始大小的某个百分比吗?

For example, half the original size

例如,原尺寸的一半

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

#7


9  

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

#8


2  

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

I use this library:

我使用这个库:

pip install python-resize-image

#9


1  

My ugly example.

我的丑陋的例子。

Function get file like: "pic[0-9a-z].[extension]", resize them to 120x120, moves section to center and save to "ico[0-9a-z].[extension]", works with portrait and landscape:

函数get file like:“pic[0-9a-z]”。[扩展]",调整大小到120x120,移动部分到中心保存到"ico[0-9a-z]。[延伸]“,与肖像和景观一起工作:

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

#10


0  

Just updating this question with a more modern wrapper This library wraps Pillow (a fork of PIL) https://pypi.org/project/python-resize-image/

只需使用更现代的包装器更新这个问题,这个库就会包装Pillow (PIL的一个分支)https://pypi.org/project/python-resize-image/

Allowing you to do something like this :-

允许你做这样的事:-

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 more examples in the above link.

在上面的链接中有更多的例子。

#11


0  

A simple method for keeping constrained ratios and passing a max width / height. Not the prettiest but gets the job done and is easy to understand:

一种简单的保持约束比率和传递最大宽度/高度的方法。不是最漂亮的,但完成了工作,很容易理解:

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

Here's a python script that uses this function to run batch image resizing.

下面是一个python脚本,它使用这个函数运行批处理图像大小调整。