如何使用PIL调整图像大小并保持其纵横比?

sat*_*ace 394 python image thumbnails python-imaging-library

是否有一种显而易见的方法可以解决这个问题?我只是想制作缩略图.

gnu*_*nud 445

定义最大尺寸.然后,通过拍摄来计算调整大小比率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
Run Code Online (Sandbox Code Playgroud)

  • 请注意,对于PIL流行的Pillow前叉的用户来说,"ANTIALIAS"不再是首选.http://pillow.readthedocs.org/en/3.0.x/releasenotes/2.7.0.html#default-filter-for-thumbnails (45认同)
  • @Eugene:尝试类似`s = img.size(); ratio = MAXWIDTH/s [0]; newimg = img.resize((s [0]*ratio,s [1]*ratio),Image.ANTIALIAS)`?(那是浮点除法:) (6认同)
  • Python 3 [PIL文档](http://pillow.readthedocs.io/en/3.1.x/reference/Image.html)表示,只有当结果图像小于原始图像时,"缩略图"才有效.因此,我猜想使用`resize`是更好的方法. (6认同)
  • 就像它说的那样,这个例子来自pil文档,而那个例子(仍然)不使用antialias标志.因为它可能是大多数人想要的,但我添加了它. (4认同)
  • PIL将新图像的高度设置为给定的大小(此处为128)并计算宽度以保持纵横比.有没有办法来修复宽度而不是高度?也许我会在另外的问题中问这个问题. (3认同)
  • 默认情况下,PIL`save()`方法质量很差,可以使用`image.save(file_path,quality = quality_value)`来改变质量. (2认同)

tom*_*von 230

此脚本将使用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') 
Run Code Online (Sandbox Code Playgroud)

  • nit:`resize`没有'PIL.Image.ANTIALIAS`选项,实际应该是`PIL.Image.LANCZOS`,虽然它们的值都是'1`,见http://pillow.readthedocs.io/ EN/3.1.X /参考/ Image.html#PIL.Image.Image.resize (4认同)
  • 如果您在Zope中使用此脚本作为外部方法,则需要"来自PIL导入图像"这一行,以避免与Zope的"图像"发生命名空间冲突. (2认同)
  • 感谢`PIL.Image.ANTIALIAS` (2认同)

小智 61

我还建议使用PIL的缩略图方法,因为它消除了你的所有比例麻烦.

但有一个重要提示:替换

im.thumbnail(size)
Run Code Online (Sandbox Code Playgroud)

im.thumbnail(size,Image.ANTIALIAS)
Run Code Online (Sandbox Code Playgroud)

默认情况下,PIL使用Image.NEAREST过滤器进行大小调整,从而获得良好的性能,但质量很差.

  • 这样,您只能减小图像的大小。无法使用“Image.thumbnail”增加尺寸。 (7认同)

muZ*_*uZk 34

总部设在@tomvon,我完成了以下工作:

调整宽度:

new_width  = 680
new_height = new_width * height / width 
Run Code Online (Sandbox Code Playgroud)

调整高度:

new_height = 680
new_width  = new_height * width / height
Run Code Online (Sandbox Code Playgroud)

然后就是:

img = img.resize((new_width, new_height), Image.ANTIALIAS)
Run Code Online (Sandbox Code Playgroud)

  • 你的变量都混淆了.你的帖子说调整宽度,然后调整高度.在`resize`调用中,你使用`new_width`来表示高度和宽度? (6认同)
  • @Robin 在 Python 2 中这会起作用。对于 Python 3,您需要将“/”替换为“//”。 (4认同)
  • 最好将它们转换为整数 (2认同)

小智 21

PIL已经可以选择裁剪图像

img = ImageOps.fit(img, size, Image.ANTIALIAS)
Run Code Online (Sandbox Code Playgroud)

  • 这只是裁剪图像,它不保持纵横比. (15认同)
  • 这并不能以任何方式回答这个问题。 (5认同)

Moh*_*med 20

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
Run Code Online (Sandbox Code Playgroud)

  • 这不会保留源图像的纵横比。它将图像强制为 200x300,并会导致图像被挤压或拉伸。 (14认同)
  • 这并不能以任何方式回答这个问题。 (2认同)

小智 12

如果您尝试保持相同的宽高比,那么您不会调整原始大小的某个百分比吗?

例如,原始尺寸的一半

half = 0.5
out = im.resize( [int(half * s) for s in im.size] )
Run Code Online (Sandbox Code Playgroud)

  • 可能是图像具有不同的大小,并且调整大小的结果需要具有统一的大小 (12认同)
  • 非常性感。此示例使用列表理解。使用生成器(用括号括起来)也可以:`out = im.resize( (int(half * s) for s in im.size) )` (2认同)

Vit*_*ile 9

如果您的调整大小限制仅在一维(宽度或高度)上,则可以将 PILImage.thumbnail与结合使用。sys.maxsize

例如,如果您想调整图像大小,使其高度不超过 100 像素,同时保持宽高比,您可以执行以下操作:

import sys
from PIL import Image

image.thumbnail([sys.maxsize, 100], Image.LANCZOS)
Run Code Online (Sandbox Code Playgroud)

请记住,这Image.thumbnail将就地调整图像大小,这与Image.resize返回调整大小的图像而不更改原始图像不同。

  • 在 Pillow 9.0.1 中,它是 PIL.Image.LANCZOS。 (4认同)
  • 我在 PIL.Image.Resampling 下找不到 LANCZOS。它直接位于 PIL.Image.LANCZOS 下 (2认同)

Sha*_*ess 6

只是用更现代的包装器更新这个问题 这个库包装了 Pillow (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()
Run Code Online (Sandbox Code Playgroud)

上面的链接中有更多示例。

  • resize_contain 看起来实际上非常有用! (3认同)

hoo*_*o-b 6

如果您不希望/不需要使用枕头打开图像,请使用以下命令:

from PIL import Image

new_img_arr = numpy.array(Image.fromarray(img_arr).resize((new_width, new_height), Image.ANTIALIAS))
Run Code Online (Sandbox Code Playgroud)


gue*_*tli 5

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))
Run Code Online (Sandbox Code Playgroud)

我使用这个库:

pip install python-resize-image
Run Code Online (Sandbox Code Playgroud)


use*_*339 5

打开你的图像文件

from PIL import Image
im = Image.open("image.png")
Run Code Online (Sandbox Code Playgroud)

使用 PIL Image.resize(size, resample=0) 方法,将图像的 (width, height) 替换为尺寸 2 元组。

这将以原始尺寸显示您的图像:

display(im.resize((int(im.size[0]),int(im.size[1])), 0) )
Run Code Online (Sandbox Code Playgroud)

这将以 1/2 的大小显示图像:

display(im.resize((int(im.size[0]/2),int(im.size[1]/2)), 0) )
Run Code Online (Sandbox Code Playgroud)

这将以 1/3 的大小显示图像:

display(im.resize((int(im.size[0]/3),int(im.size[1]/3)), 0) )
Run Code Online (Sandbox Code Playgroud)

这将以 1/4 的大小显示图像:

display(im.resize((int(im.size[0]/4),int(im.size[1]/4)), 0) )
Run Code Online (Sandbox Code Playgroud)

等等等等


小智 5

我还将添加一个保持宽高比固定的调整大小版本。在这种情况下,它将根据初始宽高比asp_rat浮点型(!))调整高度以匹配新图像的宽度。但是,要将宽度调整为高度,您只需在else循环中注释一行并取消注释另一行即可。你会看到,在哪里。

您不需要分号 (;),我保留它们只是为了提醒自己更经常使用的语言的语法。

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");
Run Code Online (Sandbox Code Playgroud)

而且,已经完成了。我尝试尽可能多地记录它,所以它很清楚。

我希望它对那里的人有帮助!