15

I'm trying to use PIL/Pillow in Python to open a PNG image. You'd think it'd be trivial, but the images are showing up corrupted.

Here's an example image:

I tried loading it and showing it, using Python 3.4 and Pillow 2.7.0:

$ python
Python 3.4.0 (v3.4.0:04f714765c13, Mar 16 2014, 19:25:23) [MSC v.1600 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import PIL.Image
>>> image = PIL.Image.open(r'C:\Users\Administrator\Dropbox\Desktop\example.png')
>>> image.show()
>>>

What I get displayed is this:

Does anyone have any idea why that is and how to solve it? (The corruption happens not only when I show it, but also when I'll try to paste it into another image, which is my original need.)

Ram Rachum
  • 84,019
  • 84
  • 236
  • 374

2 Answers2

8

As @wiredfool says, the image is being converted to RGB before it's shown. Unfortunately that means the alpha channel is simply being dropped. You want to do your own conversion that mixes the image with a white background instead.

Image.composite(image, Image.new('RGB', image.size, 'white'), image).show()

The documentation for paste shows that it ignores the alpha channel as well. You need to specify the image in two places, one for the source and one for the mask.

base.paste(image, box, image)
Community
  • 1
  • 1
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • I've seen the image get corrupted not only in `.show()` but also when I did `image.paste` of it into another image. It was corrupted in exactly the same way visually. – Ram Rachum Mar 17 '15 at 21:02
  • @RamRachum if the image you're pasting into isn't mode `RGBA` then `convert` it before the paste. – Mark Ransom Mar 17 '15 at 21:09
4

Image.show() writes the image as a BMP (on windows), then opens it with the viewer. Unfortunately the BMP writer doesn't preserve the alpha channel, so you're just viewing the RGB channels of the image.

wiredfool
  • 41
  • 1
  • I've seen the image get corrupted not only in `.show()` but also when I did `image.paste` of it into another image. It was corrupted in exactly the same way visually. – Ram Rachum Mar 17 '15 at 21:01
  • `Image.paste` has a weird api with respect to alpha. If you pass in a mask, it will use that to select what is pasted into the image. `Image.alpha_composite` is probably what you want. – wiredfool Mar 17 '15 at 21:34