pythonnumpyimage

Display numpy 2D array as an RGBImage


I want to display an RGBColor bitmap as an image I have several functions that fill the bitmap. also at some point I will add an alpha channel.

I saw similar questions but none of them worked for me. display an rgb matrix image in python

I have an RGBColor class defined as

class RGBColor:
    bytes = np.zeros(3, dtype=np.ubyte)

    # RGBColor.__new__
    def __new__(cls, *args, **kwargs):
        return super().__new__(cls)
    
    # RGBColor.__init__
    def __init__(self, r: int, g: int, b: int) -> None:
        self.bytes[0] = r
        self.bytes[1] = g
        self.bytes[2] = b

and a Bitmap defined as

class Bitmap:
    # Point.__new__
    def __new__(cls, *args, **kwargs):
        return super().__new__(cls)

    # Point.__init__
    def __init__(self, rows: int, cols: int, backColor: RGBColor) -> None:
        self.bits = np.empty( (rows,cols), dtype=RGBColor)
        for r in range(rows):
            for c in range(cols):
                self.bits[r][c] = backColor

and my attempt at displaying this is

import numpy as np
import matplotlib.pyplot as plt

    def show(self, bitmap: Bitmap):
        plt.imshow(bitmap.bits)
        plt.show()

The error I get is

File "C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\image.py", line 706, in set_data raise TypeError("Image data of dtype {} cannot be converted to "

TypeError: Image data of dtype object cannot be converted to float


Solution

  • You created an array of RGBColor objects. imshow can only handle int or float arrays, so you'd need a function to convert your object array to an int or float array. Here is an example of such a function (can certainly be optimized):

    def to_numpy(self):
        return np.array([b.bytes.tolist() for b in self.bits.flat], dtype=np.ubyte).reshape(self.bits.shape + (3,))
    

    Then you can call it like

    bitmap = Bitmap(3, 2, RGBColor(100, 50, 200))
    plt.imshow(bitmap.to_numpy())
    

    enter image description here