Search code examples
pythonnumpypython-imaging-library

Import a RGB array into a PIL image with fromarray


I have a RGB array that I would like to import in PIL with fromarray and save to disk:

import numpy as np
from PIL import Image
from PIL.PngImagePlugin import PngInfo
a = np.array([[[255, 0, 0], [0, 255, 0]],     # Red   Green
              [[0, 0, 255], [0, 0, 0]]])      # Blue  Black  
img = Image.fromarray(a, mode="RGB")   
metadata = PngInfo()                    # I need to add metadata, thus the use of Pillow and **not cv2**
metadata.add_text("key", "value")
img.save("test.png", pnginfo=metadata)

But the output image is Red Black Black Black instead of Red Green Blue Black.

Why?

How to properly import a uint8 RGB array in a PIL object and save it to PNG?

NB: Not a duplicate of convert RGB arrays to PIL image.

NB2: I also tried with a RGBA array, but the result is similar (the output image is Red Black Black Black instead of Red Green Blue Black) with:

a = np.array([[[255, 0, 0, 255], [0, 255, 0, 255]],     # Red   Green
              [[0, 0, 255, 255], [0, 0, 0, 255]]])      # Blue  Black  

Solution

  • Seems that your array needs to be of type uint8, then everything works.

    Working example:

    import numpy as np
    from PIL import Image
    from PIL.PngImagePlugin import PngInfo
    a = np.array([[[255, 0, 0], [0, 255, 0]],     # Red   Green
                  [[0, 0, 255], [0, 0, 0]]],      # Blue  Black
                 dtype=np.uint8)      
    img = Image.fromarray(a).convert("RGB")
    metadata = PngInfo()                    # I need to add metadata, thus the use of Pillow and **not cv2**
    metadata.add_text("key", "value")
    img.save("test.png", pnginfo=metadata)
    

    Cheers!