Adding local image

Hi,

Just wanted to know how to add local image to the page, I have tried "html.Img(src=’’), but it didn’t work. I have my image under same folder as my main.py.

Thanks,

4 Likes

See the solution in https://github.com/plotly/dash/issues/71 for now

1 Like

Did something change that causes that example to break? I just want to show a local image. But I couldn’t get that to work with html.Img(src='image.png'), as pointed out by other users. So I found this post, and tried it out, dropdown menu and all. Unfortunately, the example code does not load the test image:

Are there any gotchas that would make this not work?

One difference is that in your example you are listening on localhost, but I am running the server on host=0, so that I can work on this example on a vm.

I am curious about the line

@app.server.route('{}<image_path>.png'.format(static_image_route))

What is the purpose of <image_path>.png?

Nothing has changed that would break this. Could you try opening up your dev tools and seeing if there are any errors? You can also inspect the network tab to look at the request and print() some stuff in the serve_image function.

<image_path> means that whatever is placed in that location of the string will get passed into the function itself. For example, if /static/my-image.png is passed in, then the function will get the name 'my-image' in the serve_image function.

Another solution would be to base64 encode the image and set it as a string in the html.Img component directly (instead of serving the image).

Here’s a quick example:

import dash
import dash_html_components as html
import base64

app = dash.Dash()

image_filename = 'my-image.png' # replace with your own image
encoded_image = base64.b64encode(open(image_filename, 'rb').read())

app.layout = html.Div([
    html.Img(src='data:image/png;base64,{}'.format(encoded_image))
])

if __name__ == '__main__':
    app.run_server(debug=True)
1 Like

Thanks Chris I like the option of doing things with HTML. But I still want to learn to do it the Plotly/Dash way.

In the folder where I am running the script, I have a folder ‘img/’ where ‘1.png’ and ‘2.png’ live.

When I select an image from the drop-downs, the console logs a 404 error:

GET http://my.local.net:8050/static/2.png 404 (NOT FOUND)

Using print inside the serve_image callback I get:

image_path:  1
image_name:  1.png
image_directory + image_name:  img/1.png

Problem is that I don’t know where the underlying Flask server is looking to find the img/ folder. In your example, it found the Desktop folder. In my case, according to the 404 message, it is looking at http://my.local.net:8050/static/1.png. It is not literally looking at /static/ is it? (I don’t understand URL routing completely, yet)

My assumption is that the “root” directory is actually the same directory where the python script lives. Yet Dash/Flask cannot find the images.

I just ran the example code on my desktop, using the same folder structure as you, Chris. Works!

Which made me look at image_directory that you define at the top.

So on my VM I have to do

image_directory =  os.getcwd() + '/img/'

and that worked!!

I did not realize that was an absolute path. My bad.

1 Like

Yeah, that’s it exactly! Glad you figured it out :slight_smile:

FWIW, I have successfully been using base64 encode without problems. It doesn’t feel very “plotly-ish” but it gets the job done – and most importantly, it works not just on my local machine but when I deploy my app to AWS Elastic Beanstalk (the image is uploaded to an S3 bucket and called from there). However, I’m going to attempt the approach suggested here and see if I can reproduce it successfully. Static images (i.e., the company logo) are a part of every app I build!

1 Like

The correct approach with the current version of dash is to use the assets system. You can put your image files in the assets folder, and use app.get_asset_url('my-image.png') to get the url to the image.

import dash
app = dash.Dash(__name__)

app.layout = html.Div(html.Img(src=app.get_asset_url('my-image.png')))

but when I deploy my app to AWS Elastic Beanstalk

Just make sure to also include the assets folder in the package for AWS Elastic Beanstalk.

16 Likes

I used the same code, but I can’t see my image.

1 Like

Is this method suitable for svg images ?

Spoiler alert
I does not work in my case

One more following up question:
if I were using
src = ‘http://localhost:8892/notebooks/Desktop/data%20processing/automating%20report/color_gradient.png
it works great.

But src = ‘./color_gradient.png’ do not work.

Could anyone help?

Thanks!

You probably need to set your ospath to your current working directory first.

make sure the picture is in the right directory ! in my case, I had to make a directory called “assets” and place the figures there.

3 Likes

yeah, definitely this. you have to create a folder called assets and place the image there.

1 Like

This is an easy work-around:

import dash
import dash_html_components as html
import base64

app = dash.Dash()

image_filename = 'file/path' # replace with your own image
encoded_image = base64.b64encode(open(image_filename, 'rb').read())

app.layout = html.Div([
    html.Img(src='data:image/png;base64,{}'.format(encoded_image.decode()))
])

if __name__ == '__main__':
    app.run_server(debug=True)
7 Likes

@Philippe how would i control the size of the image using the above?

@zPlotlyUser Have you tried the height property under the html.Img component? I believe it resizes the image to the specified height without perverting the aspect ratio.

 app.layout = html.Div([
                html.Img(src='data:image/png;base64,{}'.format(encoded_image.decode()),
                height=300)
              ])

A post was split to a new topic: Including html plotly graphs in dash app