简体   繁体   中英

Pillow/NP: how to convert transparent mapped (indexed) PNG to RGBA when transparency is in binary format

I need to convert a transparent mapped (indexed) PNG to RGBA. Normally transparency is defined by one single color and the following code, based on Pillow and Numpy, would work:

from PIL import Image
import numpy as np

indexed = Image.open("mapped_image.png")

if indexed.mode == "P":
    is_transparent = False

    # check if transparent
    transp_byte = indexed.info.get("transparency", -1)
    for _, index in indexed.getcolors():
        if index == transp_byte:
            is_transparent = True
            break

    # convert indexed image to Numpy array
    indexed_as_np = np.asarray(indexed)

    # convert indexed image to RGB
    image = indexed.convert("RGB")

    # if transparency is confirmed then create the mask
    if is_transparent:
        mask = np.zeros(indexed_as_np.shape, dtype="uint8")
        mask[indexed_as_np != transp_byte] = 255

        # add mask to rgb image
        mask = Image.fromarray(mask)
        image.putalpha(mask)

elif indexed.mode == 'PA':
    image = indexed.convert("RGBA")

My problem is that I have to manage images where transparency is defined by multiple values, actually a binary value. I such cases transp_byte becomes something like:

b'\x00\x0e\x19#.8BLVq\x8e\x80`\x9a\xfe\x17.\xb7F\xd2\xea\xfd\xfe`\xfe\xdf\x9d\x86\xd1\xc0\xd9|\xbe\xa6\xa4\xfdt\xc2\x8a'

How should I convert such binary info into a valid mask ?

Actually, the answer was simpler than expected, as Pillow already includes such functionality. The following code solves the problem and simplifies a lot my original code:

from PIL import Image

indexed = Image.open("mapped_image.png")

if indexed.mode == "P":
    # check if transparent
    is_transparent = indexed.info.get("transparency", False)
    
    if is_transparent is False:
        # if not transparent, convert indexed image to RGB
        image = indexed.convert("RGB")
    else:
        # convert indexed image to RGBA
        image = indexed.convert("RGBA")
elif indexed.mode == 'PA':
    image = indexed.convert("RGBA")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM