1

I'm making a chess bot which will run in a chat program reacting and moving pieces according to commands from users. As such, I am trying to make it paste png images of chess pieces on top of a png background image of a chessboard by using the python package pillow.

In any other software, the chess pieces have transparent backgrounds and whatever is behind them show through but when I paste it on top of the chessboard using pillow the chess-piece gets a grey background which does not match the tile on the chessboard.

Is there a way in which I can paste the chess-piece image on top of my chessboard background without the added grey background colour of the chess-piece? Or is there an alternative way of doing this in python which will give the desired result?

I'm not done with the bot and the game logic but as an example, I have included some code illustrating how I've pasted one image on top of the other one below:

from PIL import Image

board = Image.open('assets/chessboard.png')
w_pawn = Image.open('assets/w_pawn_png_shadow_128px.png')

a_eight = (102, 30, 210, 158)  # Left, top, right and bottom coordinates of where the piece is pasted onto the board

battle_board = board.copy()
battle_board.paste(w_pawn, a_eight)
battle_board.show()

Just to quickly show what the output looks like I've included a screenshot of what a pawn looks like when it's pasted onto the board:

A white pawn in A8 with faulty background colour

enter image description here

Chessboard

white pawn

  • I think you will need to use the [`Image.alpha_composite()`](http://pillow.readthedocs.io/en/5.1.x/reference/Image.html#PIL.Image.alpha_composite) to get the effect you want. There's an example of using it to put a drawn shape on top of an image in [this answer](https://stackoverflow.com/a/43620169/355230) I once wrote — but it's the same idea. – martineau Dec 13 '20 at 21:38
  • Here's [another answer](https://stackoverflow.com/a/54426778/355230) showing the use of the `alpha_composite()` function. – martineau Dec 13 '20 at 21:44
  • Thank you, I need some time to understand this properly but at first sight, this looks promising. – Mike From Work Dec 13 '20 at 21:49
  • If you [edit] your question and add some links to the two images involved, I may be able to post a runnable answer… – martineau Dec 13 '20 at 21:51
  • ohh, nice. do these help? – Mike From Work Dec 13 '20 at 21:56

1 Answers1

1

OK, here's how to do it using the PIL.Image.alpha_composite() PIL Image class static function that I recommended in the comments. It performs an image-processing operation known as alpha compositing.

Update: I discovered there's also an Image.alpha_composite() method that does a similar operation, but does it "in-place" — which potentially could provide better performance (although the current documentation says that is currently not the case). Because that might change in the future, I've modified the code shown to make use of it to take advantage of possible future changes.

Since there's no alpha_composite_paste() function, an image the same size as the background chessboard image must first be created with a fully transparent background. The chess-piece is then pasted onto it in the desired location.

Once all that's done, you now have two identically sized images — as required by alpha_composite()— the compositing is then applied…the final step of the process.

from PIL import Image

# Two RGBA images.
board = Image.open('chessboard.png')
w_pawn = Image.open('w_pawn_png_shadow_128px.png')

a_eight = (102, 30, 210, 158)  # Left, top, right and bottom coordinates of where
                               # the piece is pasted onto the board

battle_board = board.copy()

# First make a fully transparent image the same size as the chessboard image.
tmp_img = Image.new('RGBA', battle_board.size, color=(0,0,0,0))
tmp_img.paste(w_pawn, box=a_eight)  # Paste chess-piece on it at desired posn.
battle_board.alpha_composite(tmp_img)  # Composite tmp_img onto board img "in-place".
battle_board.show()  # TaDa!

Here's the result:

resulting image showing transparency was preserved

martineau
  • 119,623
  • 25
  • 170
  • 301
  • Hey, sorry for disappearing for a while, my wifi stopped working last night and I was unable to reconnect. This looks great though! thank you so much for this! I learned a ton as well, which is always good. – Mike From Work Dec 14 '20 at 08:11
  • Was wondering…but figured is was just a temporary absence. Turns out the delay allowed me time to improve the code in my answer. – martineau Dec 14 '20 at 08:13
  • There is a silver lining then. Your solution worked perfectly and I am most grateful! – Mike From Work Dec 14 '20 at 14:20
  • FWIW, in [another answer](https://stackoverflow.com/a/67390446/355230) of mine to a related question, there's a definition of an generalized `alpha_composite_paste()` function that uses the same technique shown in this one. – martineau May 05 '21 at 17:19