将矩形图像调整为正方形,保持比例并用黑色填充背景

Posted

技术标签:

【中文标题】将矩形图像调整为正方形,保持比例并用黑色填充背景【英文标题】:Resize rectangular image to square, keeping ratio and fill background with black 【发布时间】:2017-10-29 02:19:34 【问题描述】:

我正在尝试调整一批 256 x N 像素的灰度图像(N 变化,但始终≤256)。

我的目的是缩小图像。

调整大小必须输出正方形 (1:1) 图像,其中:

调整大小的图像垂直居中 保持纵横比 剩余像素呈现黑色

从视觉上看,这将是理想的结果:

我尝试创建一个具有目标大小(例如 200 x 200)的 numpy zeroes 矩阵,但无法将调整大小的图像粘贴到其垂直中心。

欢迎使用 cv2、PIL 或 numpy 提出任何建议。

【问题讨论】:

【参考方案1】:

您可以使用Pillow 来实现:

代码:

from PIL import Image

def make_square(im, min_size=256, fill_color=(0, 0, 0, 0)):
    x, y = im.size
    size = max(min_size, x, y)
    new_im = Image.new('RGBA', (size, size), fill_color)
    new_im.paste(im, (int((size - x) / 2), int((size - y) / 2)))
    return new_im

测试代码:

test_image = Image.open('hLarp.png')
new_image = make_square(test_image)
new_image.show()

对于白色背景,您可以这样做:

new_image = make_square(test_image, fill_color=(255, 255, 255, 0))

结果:

【讨论】:

这看起来很不错,谢谢——所以.paste 的原点将位于中心? 居中,除非图像是奇数像素。 当然 - 因为我刚刚使用它而抓住了它。 此代码仅将背景调整为 min_size 并将原始图像居中放置。如何将原始图像调整为 min_size?谢谢。 我尝试在带有 python 3 的 jupyter notebook 上使用它,我不得不转换 (size - x) / 2(size - y) / 2 i> 到 int 使用 int((size - x) / 2)int((size - x) / 2)。我还必须将 RGBA 更改为 RGB 才能获得黑色背景【参考方案2】:

这是使用 OPENCV 模块解决您问题的代码(也使用 NUMPY 模块)

#Importing modules opencv + numpy
import cv2
import numpy as np

#Reading an image (you can use PNG or JPG)
img = cv2.imread("image.png")

#Getting the bigger side of the image
s = max(img.shape[0:2])

#Creating a dark square with NUMPY  
f = np.zeros((s,s,3),np.uint8)

#Getting the centering position
ax,ay = (s - img.shape[1])//2,(s - img.shape[0])//2

#Pasting the 'image' in a centering position
f[ay:img.shape[0]+ay,ax:ax+img.shape[1]] = img

#Showing results (just in case) 
cv2.imshow("IMG",f)
#A pause, waiting for any press in keyboard
cv2.waitKey(0)

#Saving the image
cv2.imwrite("img2square.png",f)
cv2.destroyAllWindows()

【讨论】:

是否可以通过.zeros方法创建一个透明背景的正方形?【参考方案3】:

PIL 具有缩略图方法,可以在保持纵横比的情况下进行缩放。从那里您只需将其粘贴到黑色背景矩形的中心即可。

from PIL import Image

def black_background_thumbnail(path_to_image, thumbnail_size=(200,200)):
    background = Image.new('RGBA', thumbnail_size, "black")    
    source_image = Image.open(path_to_image).convert("RGBA")
    source_image.thumbnail(thumbnail_size)
    (w, h) = source_image.size
    background.paste(source_image, ((thumbnail_size[0] - w) / 2, (thumbnail_size[1] - h) / 2 ))
    return background

if __name__ == '__main__':
    img = black_background_thumbnail('hLARP.png')
    img.save('tmp.jpg')
    img.show()

【讨论】:

【参考方案4】:
from PIL import Image

def reshape(image):
    '''
    Reshapes the non-square image by pasting
    it to the centre of a black canvas of size
    n*n where n is the biggest dimension of
    the non-square image. 
    '''
    old_size = image.size
    max_dimension, min_dimension = max(old_size), min(old_size)
    desired_size = (max_dimension, max_dimension)
    position = int(max_dimension/2) - int(min_dimension/2) 
    blank_image = Image.new("RGB", desired_size, color='black')
    if image.height<image.width:
        blank_image.paste(image, (0, position))
    else:
        blank_image.paste(image, (position, 0))
    return blank_image

【讨论】:

以上是关于将矩形图像调整为正方形,保持比例并用黑色填充背景的主要内容,如果未能解决你的问题,请参考以下文章

2.矩形选框工具组(选区概念)

用中心方形组件填充柔性容器

如何用Fireworks制作经典的扫光字GIF动画

调整图像大小 - 保持比例 - 没有背景图像

使用自动布局扩展方形视图以填充矩形超级视图

用背景颜色填充 png 透明度