Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Working with binary PNG images in PIL/pillow

When converting binary PNG files from an PIL Image object into a numpy array, the values are the same regardless whether the original image is inverted or not.

For example, both of these images produce identical numpy arrays.

t image t inverted image

import numpy as np
from PIL import Image
t = Image.open('t.png')
t_inverted = Image.open('t_inverted.png')
np.asarray(t)
np.asarray(t_inverted)

output of either np.asarray(t) or np.asarray(t_inverted) is :

array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
       [1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
       [1, 0, 1, 1, 0, 0, 1, 1, 0, 1],
       [1, 1, 1, 1, 0, 0, 1, 1, 1, 1],
       [1, 1, 1, 1, 0, 0, 1, 1, 1, 1],
       [1, 1, 1, 1, 0, 0, 1, 1, 1, 1],
       [1, 1, 1, 1, 0, 0, 1, 1, 1, 1],
       [1, 1, 1, 1, 0, 0, 1, 1, 1, 1],
       [1, 1, 1, 0, 0, 0, 0, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]], dtype=uint8)

I expected the 0s and 1s to be inverted as well. Why are they the same?

like image 599
waspinator Avatar asked Mar 30 '18 18:03

waspinator


People also ask

Does Pillow support PNG?

Pillow builds on this, adding more features and support for Python 3. It supports a range of image file formats such as PNG, JPEG, PPM, GIF, TIFF, and BMP.

What image types does PIL support?

Pillow reads JPEG, JFIF, and Adobe JPEG files containing L , RGB , or CMYK data. It writes standard and progressive JFIF files.

Does Pillow work with JPG?

Pillow supports a range of image file formats: PNG, JPEG, PPM, GIF, TIFF, and BMP.


1 Answers

Both those PNG files are indexed. They contain the same array of data, with just the values 0 and 1 that you see, but those values are not intended to be the colors of the pixels. They are supposed to be the indices into the palette. In the first file, the palette is

 Index     RGB Value
   0    [  0,   0,   0]
   1    [255, 255, 255]

and in the second file, the palette is

 Index     RGB Value
   0    [255, 255, 255]
   1    [  0,   0,   0]

The problem is that when the Image object is converted to a numpy array, the palette is not used, and only the array of indices is returned.

To fix this, use the convert() method of the Image object to convert the format from indexed palette to RGB colors:

t = Image.open('t.png')
t_rgb = t.convert(mode='RGB')
arr = np.array(t_rgb)
like image 78
Warren Weckesser Avatar answered Sep 22 '22 23:09

Warren Weckesser