Search code examples
pythonpython-imaging-librarytransparencyalpha

Pasting image with Alpha transpency


I have a piece of code that takes a string and constructs a graffiti-like image from that string. The letters are all individual .PNG images that are read in and pasted onto a new, longer image. My problem is that while the background alpha channel is in fact preserved, where the letters overlap it is not. Please see image.

How can I paste these letters overlapping while preserving alpha channel? It seems that both alpha_composite and blend functions need identical images to work.

It should be noted that I can do this either in Python or C++, I just used python now because it seemed very fast and easy.

IMAGE of problem

One original letter

EDIT: Here is the code. For sure there must be better ways to do this.

import sys
from PIL import Image


def openLetters(letters):

    files = {
        'A': 'A-rens.png',
        'B': 'B-rens.png',
        'C': 'C-rens.png',
        'D': 'D-rens.png',
        'E': 'E-rens.png',
        'F': 'F-rens.png',
        'G': 'G-rens.png',
        'H': 'H-rens.png',
        'I': 'I-rens.png',
        'J': 'J-rens.png',
        'K': 'K-rens.png',
        'L': 'L-rens.png',
        'M': 'M-rens.png',
        'N': 'N-rens.png',
        'O': 'O-rens.png',
        'P': 'P-rens.png',
        'Q': 'Q-rens.png',
        'R': 'R-rens.png',
        'S': 'S-rens.png',
        'T': 'T-rens.png',
        'U': 'U-rens.png',
        'V': 'V-rens.png',
        'W': 'W-rens.png',
        'X': 'X-rens.png',
        'Y': 'Y-rens.png',
        'Z': 'Z-rens.png',
    }



    images = []
    for letter in letters:
        images.append(Image.open(files[letter]))
        print "Opened:" + files[letter]


    widths, heights = zip(*(i.size for i in images))

    totalWidth = sum(widths)
    maxHeight = max(heights)

    newImage = Image.new('RGBA', (totalWidth, maxHeight))

    x_offset = 0

    for im in images:
        newImage.paste(im, (x_offset, 0), mask=0)
        x_offset += im.size[0] - 200

    newImage.save(letters + ".png")


openLetters("ANDERS")

Solution

  • If, as it sounds, you just want the easiest way, I would suggest ImageMagick which is installed on most Linux distros and is available for macOS and Windows. Just in Terminal or at Command Prompt:

    magick a.png a.png a.png +smush -140  result.png
    

    enter image description here

    Change from +smush to -smush to append vertically. Increase the 140 to overlap more, or decrease it to overlap less.


    If your ImageMagick version is older than v7, replace magick in my command with convert.


    As you didn't give me enough letters to play with, you'll have to make do with this for your Python version:

    #!/usr/bin/env python3
    
    import sys
    from PIL import Image
    
    
    w = 3000
    h = 1490
    
    newImage = Image.new('RGBA', (w, h))
    myMiserableA = Image.open('a.png').convert('RGBA')
    
    x_offset = 0
    
    for im in range(3):
        newImage.paste(myMiserableA, (x_offset, 0), mask=myMiserableA)
        x_offset += 1000
    
    newImage.save('result.png')
    

    enter image description here