Search code examples
python-3.ximagepython-imaging-libraryurllibbytesio

BytesIO replaces transparency in PNG files with black background


I want to keep transparent background at my 'image' variable.

If I write into a file, image looks fine. I mean image has a transparent background.

with urllib.request.urlopen(request) as response:
     imgdata = response.read()
     with open("temp_png_file.png", "wb") as output:
         output.write(imgdata)

However, if I keep the image data in BytesIO, transparent background becomes a black background.

with urllib.request.urlopen(request) as response:
     imgdata = response.read()
ioFile = io.BytesIO(imgdata) 
img = Image.open(ioFile)
img.show()

(Above code piece, img.show line shows an image with black background.)

How can I keep a transparent image object in img variable ?


Solution

  • Two things...


    Firstly, if you want and expect an RGBA image when opening a file with Pillow, it is best to convert whatever you get into that - else you may end up trying to display palette indices instead of RGB values:

    So change this:

    img = Image.open(ioFile)
    

    to this:

    img = Image.open(ioFile).convert('RGBA')
    

    Secondly, OpenCV's imshow() can't handle transparency, so I tend to use Pillow's show() method instead. Like this:

    from PIL import Image
    
    # Do OpenCV stuff
    ...
    ...
    
    # Now make OpenCV array into Pillow Image and display
    Image.fromarray(numpyImage).show()