Med Python Imaging Bibliotek (PIL), hvordan man komponerer et billede med en alfa kanal over et andet billede?

Jeg har to billeder, både med alpha-kanaler. Jeg ønsker at sætte et billede over de andre, hvilket resulterer i et nyt billede med en alpha-kanal, ligesom der ville ske, hvis de blev gjort i lag. Jeg vil gerne gøre det med Python billedbibliotek, men anbefalinger i andre systemer ville være fantastisk, selv den rå matematik ville være en velsignelse; jeg kunne bruge NumPy.

det virkede for mig: im.pasta(billede, max, mask) stackoverflow.com/questions/5324647/…

OriginalForfatteren Kris Kowal | 2010-07-30

3 svar

  1. 16

    Jeg kunne ikke finde en alpha komposit funktion i PIL, så her er mit forsøg på at gennemføre det med numpy:

    import numpy as np
    from PIL import Image
    
    def alpha_composite(src, dst):
        '''
        Return the alpha composite of src and dst.
    
        Parameters:
        src -- PIL RGBA Image object
        dst -- PIL RGBA Image object
    
        The algorithm comes from http://en.wikipedia.org/wiki/Alpha_compositing
        '''
        # http://stackoverflow.com/a/3375291/190597
        # http://stackoverflow.com/a/9166671/190597
        src = np.asarray(src)
        dst = np.asarray(dst)
        out = np.empty(src.shape, dtype = 'float')
        alpha = np.index_exp[:, :, 3:]
        rgb = np.index_exp[:, :, :3]
        src_a = src[alpha]/255.0
        dst_a = dst[alpha]/255.0
        out[alpha] = src_a+dst_a*(1-src_a)
        old_setting = np.seterr(invalid = 'ignore')
        out[rgb] = (src[rgb]*src_a + dst[rgb]*dst_a*(1-src_a))/out[alpha]
        np.seterr(**old_setting)    
        out[alpha] *= 255
        np.clip(out,0,255)
        # astype('uint8') maps np.nan (and np.inf) to 0
        out = out.astype('uint8')
        out = Image.fromarray(out, 'RGBA')
        return out

    For eksempel på baggrund af disse to billeder,

    img1 = Image.new('RGBA', size = (100, 100), color = (255, 0, 0, 255))
    draw = ImageDraw.Draw(img1)
    draw.rectangle((33, 0, 66, 100), fill = (255, 0, 0, 128))
    draw.rectangle((67, 0, 100, 100), fill = (255, 0, 0, 0))
    img1.save('/tmp/img1.png')

    Med Python Imaging Bibliotek (PIL), hvordan man komponerer et billede med en alfa kanal over et andet billede?

    img2 = Image.new('RGBA', size = (100, 100), color = (0, 255, 0, 255))
    draw = ImageDraw.Draw(img2)
    draw.rectangle((0, 33, 100, 66), fill = (0, 255, 0, 128))
    draw.rectangle((0, 67, 100, 100), fill = (0, 255, 0, 0))
    img2.save('/tmp/img2.png')

    Med Python Imaging Bibliotek (PIL), hvordan man komponerer et billede med en alfa kanal over et andet billede?

    alpha_composite producerer:

    img3 = alpha_composite(img1, img2)
    img3.save('/tmp/img3.png')

    Med Python Imaging Bibliotek (PIL), hvordan man komponerer et billede med en alfa kanal over et andet billede?

    Fungerer som en charme. Tak.

    OriginalForfatteren unutbu

  2. 31

    Dette ser ud til at gøre det trick:

    from PIL import Image
    bottom = Image.open("a.png")
    top = Image.open("b.png")
    
    r, g, b, a = top.split()
    top = Image.merge("RGB", (r, g, b))
    mask = Image.merge("L", (a,))
    bottom.paste(top, (0, 0), mask)
    bottom.save("over.png")
    Jeg står korrigeret 🙂 Tak for at dele.
    Nej, jeres fungerer bedre. Jeg har indarbejdet din løsning i mit projekt.
    Har lige prøvet denne ene, og (a) at det virker ganske pænt, i det mindste for quick-and-dirty opgave, jeg laver, og (b) ikke kræver numpy til at blive installeret. Bemærk, ovenstående kommentar selv.

    OriginalForfatteren Kris Kowal

  3. 21

    Pude 2.0 indeholder nu en alpha_composite funktion, der gør dette.

    img3 = Image.alpha_composite(img1, img2)

    OriginalForfatteren olt

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *