Black b64-encoded image from numpy array

# the function I use to convert array to b64
def numpy_to_b64(array):
    im_pil = Image.fromarray(array)
    if im_pil.mode != 'RGB':
        im_pil = im_pil.convert('RGB')
    buff = BytesIO()
    im_pil.save(buff, format="png")
    im_b64 = base64.b64encode(buff.getvalue()).decode("utf-8")

    return im_b64

@app.callback(
    Output('display-img', 'children'),
    [Input('graph', 'clickData')]
)
def display_click_data(clickData):
    if clickData:
        click_point_np = np.array([clickData['points'][0][i] for i in ['x', 'y']]).astype(np.float64)
        bool_mask_click = df.loc[:, 'z_x':'z_y'].eq(click_point_np).all(axis=1)
        if bool_mask_click.any():
            clicked_idx = df[bool_mask_click].index[0]
            img_vector = img_array[clicked_idx].astype(np.float64)
            img_b64 = numpy_to_b64(img_vector)
            return html.Img(
                src='data:image/png;base64,{}'.format(img_b64),
        )
    return None

where df is the dataframe I use to plot the graph, and I want interact with the graph by clicking on the data points in the graph, which displays a sub-image corresponding to the data point.

However the displayed images are all black at the moment; could you please help me on this? The values of array are within [-1, 1], is it an issue?

1 Like

I haven’t used Image before, but RGB values need to be between 0 and 256. 0 and anything negative are considered black.

What might work:

We know that the range of your array is 1-(-1)==2. So you need to transform your array to represent numbers from 0 to 256:

array = 255*(array + 1)/2 
# the rest ...

Try this, as it should not be an issue with Dash necessarily.

Thanks! Yes it is not an issue with Dash.

I scale the value as follows:

array = ((array + 1) / (2))
array = np.uint8(255 * array)

it shows the image, but in grey scale
image

Is it possible to make it in color, like what is done by cmap in matplotlib.pyplot.imshow() as
image