1

I'm trying to adapt the code from this page with a slightly different purpose:

Mapping an image with random coordinates, using PIL, without them stay one on top of the other

I'm using a black background in the back with 2 images (a white X and an orange dot) made with transparent background.The result is a complete black background.I'd like to have the orange dot behind the white X cross but unfortunately nothing is visible.

https://i.ibb.co/WfZ4NhQ/background2.png

https://i.ibb.co/Lvm3CbD/orangedot.png

https://i.ibb.co/23mXjqm/whiteX.png

https://i.ibb.co/FYMg8QL/test.png

from PIL import Image
import random


#whiteX = 200x200
#orangedot = 30x30

background2 = Image.open('background2.png')
whiteX = Image.open('whiteX.png')
orangedot = Image.open('orangedot.png')

positionxorangedot = random.randint(30, 170)
positionyorangedot = random.randint(0, 100)


background2.paste(whiteX)
background2.paste(orangedot, (positionxorangedot, positionyorangedot), orangedot)


background2.save("test.png")

background2.show()

As a last action I would like to save (for example 500 times) the output files in jpg or similar format. I have tried various solutions without being able to write anything really functional... any help really appreciated! How do you suggest I proceed?

miken32
  • 42,008
  • 16
  • 111
  • 154
Albert
  • 27
  • 5
  • have look: https://stackoverflow.com/a/30228308/8133524 – Ramesh May 04 '21 at 16:52
  • 1
    You have asked a number of questions. Please focus on just one question per question. Which qould you like this one to be: `how do i create and save 500 files?` or `how can i overlay one image on another?` or ...? – wwii May 04 '21 at 18:44
  • Thanks Ramesh! I had not thought about those solutions and I must say that they are very interesting !! You gave me some great ideas :) . – Albert May 04 '21 at 19:24
  • Hello wwii! You are right, the correct question contextualized in the post was "how to make correctly overlapping images appear on a black background" because I was just getting a black background and nothing more. I would say that the answer given by martineau address exactly my problem. – Albert May 04 '21 at 19:30

1 Answers1

2

Your question is very similar to what's in my answer to one titled How do I make the background of an image, that is pasted on top of another image, transparent in pillow? with a few (relatively minor) differences:

  1. The background image needed to first be converted into "RGBA" mode (because it's a paletted, "P" mode, image)
  2. Multiple images are being composited.

Here the results (see linked answer for explanation):

from PIL import Image
import random


#bckgnd = 200x200
#whiteX = 200x200
#orangedot = 30x30

bckgnd = Image.open('background2.png').convert('RGBA')  # Convert to mode supporting alpha.

whiteX = Image.open('whiteX.png')
tmp_img = Image.new('RGBA', bckgnd.size, color=(0,0,0,0))
tmp_img.paste(whiteX)  # Assumes it's the same size as background image.
bckgnd.alpha_composite(tmp_img)

orangedot = Image.open('orangedot.png')
orangedot_x, orangedot_y = random.randint(30, 170), random.randint(0, 100)
tmp_img = Image.new('RGBA', bckgnd.size, color=(0,0,0,0))
tmp_img.paste(orangedot, (orangedot_x, orangedot_y))
bckgnd.alpha_composite(tmp_img)

bckgnd.save("test.png")
bckgnd.show()

Sample test.png file generated:

test.png file generated

Update

Since the above contains a lot of repeated code, and in principle one should generally strive to keep things DRY, here's an alternative implementation that defines a function to do the image compositing work.

from PIL import Image
import random


def alpha_composite_paste(img1, img2, box=None):
    ''' Alpha composite paste one image over another. Both `img1` and `img2` can
        be either an image object or the file path of an image file. The `box`
        argument is either a 2-tuple giving the upper left corner, a 4-tuple
        defining the left, upper, right, and lower pixel coordinate, or None
        (same as (0, 0)). Both images must be RGBA mode.

        For convenience, returns modified img1.
    '''
    if isinstance(img1, str):  # Image file path?
        img1 = Image.open(img1)
    if isinstance(img2, str):  # Image file path?
        img2 = Image.open(img2)
    # Make fully transparent image the same size as img1.
    tmp_img = Image.new('RGBA', img1.size, color=(0,0,0,0))
    tmp_img.paste(img2, box)  # Paste img2 on top of that.
    img1.alpha_composite(tmp_img)
    return img1


bckgnd = Image.open('background2.png').convert('RGBA')  # Convert to needed mode.

alpha_composite_paste(bckgnd, 'whiteX.png')

orangedot_x, orangedot_y = random.randint(30, 170), random.randint(0, 100)
alpha_composite_paste(bckgnd, 'orangedot.png', (orangedot_x, orangedot_y))

bckgnd.save("test.png")
bckgnd.show()
martineau
  • 119,623
  • 25
  • 170
  • 301