web-dev-qa-db-fra.com

Redimensionnez l'image rectangulaire en carré, en conservant le rapport et en remplissant l'arrière-plan de noir

J'essaie de redimensionner un lot d'images en niveaux de gris de 256 x N pixels (N varie, mais est toujours ≤256).

Mon intention est de réduire l'échelle des images.

Le redimensionnement devrait produire une image carrée (1: 1), avec:

  • image redimensionnée centrée verticalement
  • rapport d'aspect maintenu
  • pixels restants rendus noirs

Visuellement, ce serait le résultat souhaité:

enter image description here

J'ai essayé de créer une matrice de zéros numpy avec la taille cible (par exemple 200 x 200) mais je n'ai pas pu coller l'image redimensionnée dans son centre vertical.

Toutes suggestions utilisant cv2, PIL ou numpy sont les bienvenues.

20
pepe

Vous pouvez utiliser Pillow pour accomplir cela:

Code:

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

Code de test:

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

Pour un fond blanc, vous pouvez faire:

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

Résultat:

enter image description here

24
Stephen Rauch

PIL a la méthode des vignettes qui évoluera en gardant le rapport hauteur/largeur. De là, il vous suffit de le coller centré sur votre rectangle de fond noir.

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()
3
clockwatcher
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
0
Joseph

Voici un code qui résout votre question avec le module OPENCV (en utilisant également le module 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()
0
Diroallu