3

I have a question. For example, I have 3 images (50x50px), and I need the images to be combined into one image (for example, the output is 500x500px). My problem is that I don’t know how to combine the images vertically every time when 3 images are filled horizontally. And so step by step. Right now I only know how to fill in two lines (once horizontally and once vertically). I will be glad to any of your help. Thanks! Below is the code that does what I need, but I also want to be able to resize the image for a new row or column:

img = 'path_to_image'
new_im = Image.new('RGB', (400, 400))
for x in range(0, 400, img.width):
    for y in range(0, 400, img.height):
        new_im.paste(img, (x, y))
Paladond
  • 39
  • 4

1 Answers1

0

Do you mean like this?

import numpy as np
img_1 = np.ones((2, 2))
img_2 = np.ones((2, 2)) * 2
img_3 = np.ones((2, 2)) * 3

img = np.hstack([img_1, img_2, img_3])
# array([[1., 1., 2., 2., 3., 3.],
#        [1., 1., 2., 2., 3., 3.]])

new_shape = np.array([6, 12])
new_img = np.tile(img, reps=new_shape // np.array(img.shape))
# array([[1., 1., 2., 2., 3., 3., 1., 1., 2., 2., 3., 3.],
#        [1., 1., 2., 2., 3., 3., 1., 1., 2., 2., 3., 3.], 
#        [1., 1., 2., 2., 3., 3., 1., 1., 2., 2., 3., 3.],
#        [1., 1., 2., 2., 3., 3., 1., 1., 2., 2., 3., 3.],
#        [1., 1., 2., 2., 3., 3., 1., 1., 2., 2., 3., 3.],
#        [1., 1., 2., 2., 3., 3., 1., 1., 2., 2., 3., 3.]])

If you want to additionally resize your image maybe this answer might help you.

This approach is agnostic on how you get your img. The important thing is that you have to make sure that all combinations of initial images will add up to the final shape.

If you have images of shape 50x50 and a final shape of 500x500 and you combine always 2, 3 or 4 of them together you have :

  • 500 / (2*50) = 5
  • 500 / (3*50) = 3.33
  • 500 / (4*50) = 2.5

So this wont work for you. You have two options, either you crop the pixels that don't fit or you resize the resulting image.

  • 500 / (2*50) = 5
  • 500 / (3*50) = 3.33 -> 4, resize / crop 500x600 to 500x500
  • 500 / (4*50) = 2.5 -> 3, resize / crop 500x600 to 500x500
import numpy as np
img_1 = np.ones((2, 2))
img_2 = np.ones((2, 2)) * 2
img_3 = np.ones((2, 2)) * 3
img_4 = np.ones((2, 2)) * 4
img_list = np.array([img_1, img_2, img_3, img_4])

# Get random combination of 2-4 images
img_dx_rnd = np.random.choice(np.arange(4), np.random.randint(2, 5), replace=False)
img = np.hstack([*img_list[img_dx_rnd]])

new_shape = np.array([6, 12])
reps = np.ceil(new_shape / np.array(img.shape)).astype(int)
new_img = np.tile(img, reps=reps)

# Cropping
new_img = new_img[:new_shape[0], :new_shape[1]]

# Resizing
from skimage.transform import resize
new_img = resize(new_img, new_shape)
scleronomic
  • 4,392
  • 1
  • 13
  • 43
  • I added a link for resizing the image. what is it than that you want to see? Could you explain again what you want to achieve? – scleronomic Mar 09 '20 at 11:35
  • I can have 2, 3 or 4 small pictures - it doesn’t matter. I need to make an output image of them (for example, 500x500px). But small images each time are randomly selected among themselves from the list and concatenated. – Paladond Mar 09 '20 at 11:47
  • I edit my answer, I guess I understand your question better now. Is this croping / resizing your problem? – scleronomic Mar 09 '20 at 12:19
  • I can link with you via email for more detailed discussion the task? – Paladond Mar 09 '20 at 15:23