jeudi 21 janvier 2021

How to avoid overlapping when drawing image on a canvas

I am trying to draw n number of logos on a canvas. Currently, this is the issue I am facing.

enter image description here

As you can see, the amazon, ader and nvidia logos are drawn on top of each other. My goal is to draw these logos randomly within the canvas while avoid overlapping between them. To keep them in the canvas, this is what I do:

    primary_logo_x = random.randint(0, canvas_width - primary_logo_width)
    primary_logo_y = random.randint(0, canvas_height - primary_logo_height)

The code always draws at least one logo and that is the first primary_logo. If the user selects 2 logos, another logo will need to be drawn away from primary_logo. If the user selects 3, another logo will be drawn away from the previous two and so on..

This if-forloop nest checks if n is greater than 1 and if so, draws the additional n-1 logos.

    if n > 1:

        # The reason why its quantity - 1 is because if the user requires 2, one logo was already drawn and that
        # was the primary logo so now we just have to draw a new one.
        for i in range(0, quantity-1):

            # Get the last logo's location from locations_used. Save in tuple.
            # Get the last logo's dimensions. Save in tuple.
            last_logo_location_x, last_logo_location_y = locations_used[-1]
            last_logo_width, last_logo_height = used_logos_dimensions[-1]

            # Get a sample of logos with exception to the ones already used. This line ensures that
            # There will not be repeats of the logo on the canvas.
            logos = random.sample(set(os.listdir(current_dir + '/Logos/')) - set(logos_used), quantity-1)
            additional_logo_name = random.choice(logos)

            # Randomly choose one of the logos and open it as a PIL image.
            additional_logo = Image.open(current_dir + '/Logos/' + additional_logo_name).convert('RGBA')

            # Have the logo go through augmentation transformations. Get the resulting logo and update png with it.
            additional_logo = transformations(additional_logo, canvas)

            # Take the random logo's dimensions
            additional_logo_w, additional_logo_h = additional_logo.size

            additional_logo_x = random.randint(0, canvas_width - additional_logo_w)
            additional_logo_y = random.randint(0, canvas_height - additional_logo_h)

            # Paste the drawn logo on the canvas. Positioning the 2nd logo on the top-left corner for now.
            text_img.paste(additional_logo, (additional_logo_x, additional_logo_y), mask=additional_logo)

            # Drawing the final image.
            img_draw = ImageDraw.Draw(text_img)

            img_draw.rectangle((additional_logo_x, additional_logo_y, additional_logo_x + additional_logo_w, additional_logo_y + additional_logo_h), outline='Red', width=3)

            # Adding the used logo to the logos_used list to avoid reusing them in the same canvas.
            logos_used.append(additional_logo_name)

In short, I am trying to figure out a logic for additional_logo_x, additional_logo_y to keep it away from primary_logo_x, primary_logo_y




Aucun commentaire:

Enregistrer un commentaire