Create PNG from base64 encoded html.Img src

So I have an html.Img component in my Dash app that displays an image based on user input. Since some precomputation is required for the initial image to be created, it is saved as a local file temporarily to encode into a base64 string readable by the html.Img component:

encoded = base64.b64encode(open('output-1.png', 'rb').read())
return 'data:image/png;base64,{}'.format(encoded.decode())

The thing is, since the user would be creating multiple of these images in a session, I have it so that it saves a list of these base64 strings in one place.

I want to provide the option for the user to download any of these images at any time using a button and the dcc.Download() option. How would I go about recreating the PNG file from the base64 string to be sent to the dcc.Download for the user to download the image onto their system?

Hi @hypervalent,

while it does not answer your question, maybe this helps you to get an idea

Hello @hypervalent,

I dont think you would need to convert it. How are you storing this data currently in the user session?

If you can access this store, you should be able to utilize the method @AIMPED mentioned.

Stackoverflow has a few snippets on doing this. This is probably how’d i’d do it given a base64 string as input. Granted this isn’t specific to dash/plotly.

The data is simply being stored as a string, in the exact same format as returned from the code snippet in the question.
Which is weird since when the base64 string is created, it displays perfectly fine when passed in the src of the html.Img component. However trying to pull it from the dcc.Store without changing anything and passing it into another html.Img src argument just doesn’t want to display anything.

@hypervalent,

I think you need to strip out the beginning part when you are going to save it, you should be just using the data of the image, and not the things that tell it how to read the stream. :grin:

1 Like

Ah I tried that and it seemed to have worked. I didn’t realize that the beginning part actually isn’t needed and was banging my head for so long trying to find a solution.

Thank you!

1 Like