Search code examples
pythonnumpymatplotlibpng

How to print greyscale image with alpha using matplotlib?


I' am writing a simple PNG parser that can decode PNG data and print raw pixels using matplotlib. I have no problem printing RGB, RGBA and pure greyscale.

import matplotlib.pyplot as plt
import numpy as np

with PngParser() as png:
    if png.greyscale:
        plt.imshow(np.array(png.reconstructed_data).reshape((png.height, png.width)), cmap='gray', vmin=0, vmax=255)
        plt.show()
    elif png.greyalhpa:
        ?
    else:
        # RGB, RGBA
        plt.imshow(np.array(png.reconstructed_data).reshape((png.height, png.width, png.bytesPerPixel)))
        plt.show()

Where png.reconstructed_data is a simple array of pixels.

Unfortunatelly, matplotlib don't explicitly supports this kind of image. Here is a quote from documentation:

Supported array shapes are:

(M, N): an image with scalar data. The values are mapped to colors using normalization and a colormap. See parameters norm, cmap, vmin, vmax.

(M, N, 3): an image with RGB values (0-1 float or 0-255 int).

(M, N, 4): an image with RGBA values (0-1 float or 0-255 int), i.e. including transparency. The first two dimensions (M, N) define the rows and columns of the image.

Our shape would be (M, N, 2) .

Is there any workaround for this problem?


Solution

  • I think turning the grayscale image into an RGB image is the best workaround. You do this by replicating the image in each channel. This will allow you to handle images with different alpha values for each pixel.

    height = 10
    width = 10
    
    # example image
    img = np.random.random(size=(height, width, 2))
    
    # separate out image and alpha channel
    grayscale = img[:, :, 0]
    alpha = img[:, :, 1]
    
    # repeat grayscale image for each channel 
    rgb_img = np.dstack((grayscale, grayscale, grayscale, alpha))
    
    fig, ax = plt.subplots(1, 3)
    ax[0].imshow(grayscale, cmap='gray')
    ax[1].imshow(alpha)
    ax[2].imshow(rgb_img)
    

    enter image description here