简体   繁体   English

Python PIL 调整大小是否保持纵横比?

[英]Does Python PIL resize maintain the aspect ratio?

Does PIL resize to the exact dimensions I give it no matter what?无论如何,PIL 是否会调整到我给它的确切尺寸? Or will it try to keep the aspect ratio if I give it something like the Image.ANTIALIAS argument?或者如果我给它类似Image.ANTIALIAS参数,它会尝试保持纵横比吗?

Yes it will keep aspect ratio using thumbnail method:是的,它将使用缩略图方法保持纵横比:

image = Image.open(source_path)
image.thumbnail(size, Image.ANTIALIAS)
image.save(dest_path, "JPEG")

How do I resize an image using PIL and maintain its aspect ratio? 如何使用 PIL 调整图像大小并保持其纵横比?

Image.resize from PIL will do exactly as told.来自 PIL 的 Image.resize 将完全按照说明进行。 No behind scenes aspect ratio stuff.没有幕后长宽比的东西。

最近的 Pillow 版本(自 8.3 起)具有以下方法来调整图像大小以适应给定的框并保持纵横比。

image = ImageOps.contain(image, (2048,2048))

Yes.是的。 the thumbnail() method is what is needed here... One thing that hasn't been mentioned in this or other posts on the topic is that 'size' must be either a list or tuple. thumbnail() 方法是这里需要的......在这个或关于该主题的其他帖子中没有提到的一件事是“大小”必须是一个列表或元组。 So, to resize to a maximum dimension of 500 pixels, you would call: image.thumbnail((500,500), Image.ANTIALIAS)因此,要将最大尺寸调整为 500 像素,您可以调用:image.thumbnail((500,500), Image.ANTIALIAS)

See also this post on the subject: How do I resize an image using PIL and maintain its aspect ratio?另请参阅有关该主题的帖子: 如何使用 PIL 调整图像大小并保持其纵横比?

No, it does not.不,不是的。 But you can do something like the following:但是您可以执行以下操作:

im = PIL.Image.open("email.jpg"))
width, height = im.size
im = im.resize((width//2, height//2))

Here the height and width are divided by the same number, keeping the same aspect ratio.这里高度和宽度除以相同的数字,保持相同的纵横比。

Okay, so this requires a couple of lines of code to get what you want.好的,所以这需要几行代码来获得你想要的。

First you find the ratio, then you fix a dimension of the image that you want (height or width).首先找到比率,然后确定所需图像的尺寸(高度或宽度)。 In my case, I wanted height as 100px and let the width adjust accordingly, and finally use that ratio to find new height or new width.在我的例子中,我希望高度为 100px 并让宽度相应地调整,最后使用该比率来找到新的高度或新的宽度。

So first find the dimensions:所以首先找到尺寸:

width, height = logo_img.size
ratio = width / height
      

Then, fix one of the dimension:然后,修复其中一个维度:

new_height = 100

Then find new width for that height:然后找到该高度的新宽度:

new_width = int(ratio * new_height)
            
logo_img = logo_img.resize((new_width, new_height))

It depends on your demand, if you want you can set a fixed height and width or if you want you can resize it with aspect-ratio.这取决于您的需求,如果您愿意,您可以设置固定的高度和宽度,或者如果您愿意,您可以使用纵横比调整它的大小。

For the aspect-ratio-wise resize you can try with the below codes :对于纵横比调整大小,您可以尝试使用以下代码:

To make the new image half the width and half the height of the original image:使新图像的宽度和高度分别为原始图像的一半:

from PIL import Image
im = Image.open("image.jpg")
resized_im = im.resize((round(im.size[0]*0.5), round(im.size[1]*0.5)))
        
#Save the cropped image
resized_im.save('resizedimage.jpg')

To resize with fixed width and ratio wise dynamic height :使用固定宽度和比例动态高度调整大小:

from PIL import Image
new_width = 300
im = Image.open("img/7.jpeg")
concat = int(new_width/float(im.size[0]))
size = int((float(im.size[1])*float(concat)))
resized_im = im.resize((new_width,size), Image.ANTIALIAS)
#Save the cropped image
resized_im.save('resizedimage.jpg')

Recent versions of Pillow have some useful methods in PIL.ImageOps .最近版本的 Pillow 在PIL.ImageOps中有一些有用的方法。

Depending on exactly what you're trying to achieve, you may be looking for one of these:根据您要实现的具体目标,您可能正在寻找其中之一:

  • ImageOps.fit(image, size [, …]) (docs) – resizes your image, maintaining its aspect ratio, and crops it to fit the given size ImageOps.fit(image, size [, …]) (docs) – 调整图像大小,保持其纵横比,并裁剪它以适合给定大小

  • ImageOps.contain(image, size [, …]) (docs) – resizes your image, maintaining its aspect ratio, so that it fits within the given size ImageOps.contain(image, size [, …]) (docs) – 调整图像大小,保持其纵横比,使其适合给定大小

One complete example:一个完整的例子:

import PIL.Image


class ImageUtils(object):
    @classmethod
    def resize_image(cls, image: PIL.Image.Image, width=None, height=None) -> PIL.Image.Image:
        if height is None and width is not None:
            height = image.height * width // image.width
        elif width is None and height is not None:
            width = image.width * height // image.height
        elif height is None and width is None:
            raise RuntimeError("At lease one of width and height must be present")
        return image.resize((width, height))


def main():
    ImageUtils.resize_image(PIL.Image.open("old.png"), width=100).save("new.png")


if __name__ == '__main__':
    main()

我认为以下是最简单的方法:

Img1 = img.resize((img.size),PIL.Image.ANTIALIAS)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM