0

I'm trying to put 3 images inside a background image with random coordinates, using the Python Imaging Library (PIL). I have attached all the necessary images just below the code.

#background = 800x400
#red,blue,green = 120x48

background = Image.open('background.png')
red = Image.open('red.png')
blue = Image.open('blue.png')
green = Image.open('green.png')

positionxred = random.randint(0, 800)
positionyred = random.randint(0, 400)

positionxblue = random.randint(0, 800)
positionyblue = random.randint(0, 400)

positionxgreen = random.randint(0, 800)
positionygreen = random.randint(0, 400)

background.paste(red, (positionxred, positionyred), red)
background.paste(blue, (positionxblue, positionyblue), blue)
background.paste(green, (positionxgreen, positionygreen), green)

background.save("test.png")

Attachments:

background

background

red

red

blue

blue

green

green

test

test

my goal is that the area coordinates of the red, blue, green images are not the same, because if they are, the images will stay on top of each other as shown in the attached test image.
As you can see, the size of the images red, blue and green are 120x48, that is, 5760 units of area.
The background image has 400x800, with a total of 320000 units of area.
I need a way that the 5760 area units of each image do not stay on top of the other image, using some looping command, how should I proceed?

Lucas Tesch
  • 137
  • 1
  • 10
  • 1
    Do you also want to keep the full image within the 400x800 and not allow it to get cropped off the edge of the background? Currently `random.randint(0, 800)` and `random.randint(0, 400)` allow for a left-edge value greater than the width and height of the images, as the blue and yellow images are here: https://i.imgur.com/9mHCNfI.png – chickity china chinese chicken Feb 02 '19 at 01:55

1 Answers1

1

The core part is re-try pasted points when all image not overlap:

from PIL import Image
import random

"""
[ref](https://www.geeksforgeeks.org/find-two-rectangles-overlap/)
"""
def is_overlap(l1, r1, l2, r2):
    if l1[0] > r2[0] or l2[0] > r1[0]:
        return False

    if l1[1] > r2[1] or l2[1] > r1[1]:
        return False

    return True

background = Image.open('background.png')
paste_image_list = [Image.open('red.png'), Image.open('blue.png'), Image.open('green.png')]
alread_paste_point_list = []

for img in paste_image_list:
    # if all not overlap, find the none-overlap start point
    while True:
        # left-top point
        # x, y = random.randint(0, background.size[0]), random.randint(0, background.size[1])

        # if image need in the bg area, use this
        x, y = random.randint(0, max(0, background.size[0]-img.size[0])), random.randint(0, max(0, background.size[1]-img.size[1]))

        # right-bottom point
        l2, r2 = (x, y), (x+img.size[0], y+img.size[1])

        if all(not is_overlap(l1, r1, l2, r2) for l1, r1 in alread_paste_point_list):
            # save alreay pasted points for checking overlap
            alread_paste_point_list.append((l2, r2))
            background.paste(img, (x, y), img)
            break

background.save("test.png")

# check like this, all three rectangles all not overlapping each other
from itertools import combinations
assert(all(not is_overlap(l1, r1, l2, r2) for (l1, r1), (l2, r2) in combinations(alread_paste_point_list, 2)))
whiledoing
  • 51
  • 6