PIL merge of two images with alpha channels - not working as expected

前端 未结 1 708
说谎
说谎 2021-01-03 03:54

There\'s a bunch of questions here on SO which provide answers to the present question, however the output is not the expected.

The goal is to merge two RGBA images.

相关标签:
1条回答
  • 2021-01-03 04:21

    From your initial description, the following idea seems to be equivalent. Let X, Y be two RGBA images. Merge X and Y considering the bands RGB from X and the bands RGBA from Y, producing an image Z. Set the band A in Z to that of the band A in X. This contradicts your final statement, but it seems to give the expected output in this situation.

    So, this is the code:

    image = '1.png'
    watermark = '2.png'
    
    wmark = Image.open(watermark)
    img = Image.open(image)
    
    ia, wa = None, None
    if len(img.getbands()) == 4:
        ir, ig, ib, ia = img.split()
        img = Image.merge('RGB', (ir, ig, ib))
    if len(wmark.getbands()) == 4:
        wa = wmark.split()[-1]
    
    img.paste(wmark, (0, 0), wmark)
    if ia:
        if wa:
            # XXX This seems to solve the contradiction, discard if unwanted.
            ia = max_alpha(wa, ia)
        img.putalpha(ia)
    
    img.save('result.png')
    

    where the function max_alpha is:

    def max_alpha(a, b):
        # Assumption: 'a' and 'b' are of same size
        im_a = a.load()
        im_b = b.load()
        width, height = a.size
    
        alpha = Image.new('L', (width, height))
        im = alpha.load()
        for x in xrange(width):
            for y in xrange(height):
                im[x, y] = max(im_a[x, y], im_b[x, y])
        return alpha
    

    This new function seems to take into consideration the contradiction mentioned.

    0 讨论(0)
提交回复
热议问题