如何使用 PIL getbbox 将图像大小调整为最大可能大小?

时间:2021-08-01 19:48:05

标签: image python-imaging-library image-resizing

我正在尝试将精灵大小调整为 96x96 边界,同时保持纵横比。

以下代码:

im.getbbox()

返回一个包含精灵边界的元组(原始背景是透明的),我被困在下一部分 - 我想获取图像的那部分并将其调整为可能在 96x96 内尽可能大的大小边界

以下是来自 Pokemon 的一些精灵的示例:

enter image description here

由于有些是 80x80,有些是 64x64,最大的是 96x96,我想用 im.getbbox() 有效地选择精灵的内容,然后将其放大以适合 96 像素的白色背景。< /p>

有人可以帮忙吗?我不确定如何在范围内最大化它

我目前的代码如下:

x = 0
for dirname, dirs, files in os.walk(path):
    for filename in files:
        x+=1
        path = dirname + "/" + filename
        print(path)
        
        im = Image.open(path)
        
        fill_color = (255,255,255)
        im = im.convert("RGBA")
        if im.mode in ('RGBA', 'LA'):
            background = Image.new(im.mode[:-1], im.size, fill_color)
            background.paste(im, im.split()[-1])
            im = background

        imResize = ImageOps.fit(im, (96, 96), Image.BOX, 0, (0.5, 0.5))
        imResize.save("dataset/images/" + str(x) + '.png', 'PNG')

它获取图像并将其粘贴到白色背景上,并将大小设置为 96 像素。这对于原生 96px 图像很好,但较小图像的纵横比被破坏了。通过能够将它们放大到 96 像素图像的最大边界,它应该可以防止这种情况发生

谢谢!

1 个答案:

答案 0 :(得分:0)

好的,我自己拍的照片,在这里:

zY28f_64.png,   zY28f_80.png  , zY28f_96.png

zY28f_64.pngzY28f_80.png zY28f_96.png

以代码结束:

from PIL import Image, ImageOps
import os



path= 'images'

x = 0
for dirname, dirs, files in os.walk(path):
    for filename in files:
        x+=1
        path = dirname + "/" + filename
        print(path)
        
        im = Image.open(path)
        
        im.show()
        
        fill_color = (255,255,255)
        im = im.convert("RGBA")
        if im.mode in ('RGBA', 'LA'):
            background = Image.new(im.mode[:-1], im.size, fill_color)
            # background.paste(im, im.split()[-1])
            background.paste(im)
            im = background
        im_inv = ImageOps.invert(im)   ### make white background black
        imResize = ImageOps.fit(im.crop(im_inv.getbbox()), (96, 96), Image.BOX, 0, (0.5, 0.5))  # im.crop crop on box got from image with black background, Image.getbbox works only with black bacground returning biggest box containing non zero(non black ) pixels
        
        imResize.show()
        
        # imResize.save("dataset/images/" + str(x) + '.png', 'PNG')

输出:

zY28f_64.png2.png , zY28f_80.png1.png , zY28f_96.png3.png

zY28f_64.png2.png zY28f_80.png1.png zY28f_96.png3.png

这里的主要变化:

使白底变黑

im_inv = ImageOps.invert(im)

从黑色背景图像获得的框上的 im.crop 裁剪,Image.getbbox 仅适用于黑色背景,返回包含非零(非黑色)像素的最大框

imResize = ImageOps.fit(im.crop(im_inv.getbbox()), (96, 96), Image.BOX, 0, (0.5, 0.5))

由于 ImageOps.fit(...) 行返回切碎的图像,不确定它是如何工作的,为了保留整个数字,我使用 PIL Image.resize() not resizing the picture 中的代码获取:

from PIL import Image, ImageOps
import os
import math


path= 'images'

x = 0
for dirname, dirs, files in os.walk(path):
    for filename in files:
        x+=1
        path = dirname + "/" + filename
        print(path)
        
        im = Image.open(path)
        

        
        fill_color = (255,255,255)
        im = im.convert("RGBA")
        if im.mode in ('RGBA', 'LA'):
            background = Image.new(im.mode[:-1], im.size, fill_color)
            # background.paste(im, im.split()[-1])
            background.paste(im)
            im = background
        im_inv = ImageOps.invert(im)
        
        imResize = im.crop(im_inv.getbbox())
        
        width, height = imResize.size
        print(width, height)
        if height > width:
            ratio = math.floor(height / width)
            newheight = ratio * 96
            print(imResize, ratio, newheight)
            imResize = imResize.resize((96, newheight))
        else:
            ratio = math.floor(width /height )
            newwidth = ratio * 96
            print(imResize, ratio, newwidth)
            imResize = imResize.resize((newwidth, 96))
        

        
        imResize.show()
        print(imResize.size)
        
        imResize.save(path + str(x) + '.png', 'PNG')

输出:

zY28f_64.png2.png , zY28f_80.png1.png , zY28f_96.png3.png

64 80 96