4

I have a FastAPI app that gets an image from an API. This image is stored in a variable with type: bytes.

I want to display the image in HTML/Jinja2 template (without having to download it). I followed many tutorials but couldn't find the solution.

Here is what I came up with so far:

@app.get("/{id}")
async def root(request: Request, id: str):
    picture = await get_online_person()

    data = base64.b64encode(picture)  # convert to base64 as bytes
    data = data.decode()  # convert bytes to string

    # str_equivalent_image = base64.b64encode(img_buffer.getvalue()).decode()
    img_tag = '<img src="data:image/png;base64,{}">'.format(data)
    return templates.TemplateResponse(
        "index.html", {"request": request, "img": img_tag}
    )

All I get in the HTML is this: (as text on the page, not from source code)

    <img src="data:image/png;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQICAQECAQEBAgICAgICAgICAQICAgICAgICAgL/2wBDAQEBAQEBAQEBAQECAQEBAgICAgI
CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgL/wgARCAQABAADASIAA
hEBAxEB/8QAHgAAAQUBAQEBAQAAAAAAAAAABQIDBAYHAQgACQr/xAAcAQACAwEBAQEAAAAAAAAAAAACAwABBAUGBwj/2gAMAwEAAhADEAAAAfEpwSR+a+9IPR3c7347iwscmWyYchEIJjn+MbJj/c4FFbbb9J5....................

Note: For people who are marking my question to a duplicate talking about urllib, I cannot use urllib because the image I'm getting is from ana API, and using their direct url will result in a 403 Forbidden, so I should use their python API to get the image.

Chris
  • 18,724
  • 6
  • 46
  • 80
Kaiss B.
  • 249
  • 1
  • 12
  • I tried this tutorial: https://blog.furas.pl/python-how-to-display-image-without-saving-in-file-using-bytesio-and-base64-string-in-url-gb.html but I get the error `'bytes' object has no attribute 'getvalue'` – Kaiss B. Sep 15 '22 at 00:06
  • Does this answer your question? [Why does parsing a webpage with beautiful soup leads to src attributes of images with values as base64 strings?](https://stackoverflow.com/questions/70959330/why-does-parsing-a-webpage-with-beautiful-soup-leads-to-src-attributes-of-images) – ti7 Sep 15 '22 at 00:07
  • No it does not, because in my case I cannot use urllib (please check my explanation in the edit above). Thank you. – Kaiss B. Sep 15 '22 at 00:15

1 Answers1

3

On server side—as shown in the last section of this answer—you should return only the base64-encoded string in the context of the TemplateResponse (without using the <img> tag, as shown in your question):

# ...
base64_encoded_image = base64.b64encode(image_bytes).decode("utf-8")
return templates.TemplateResponse("index.html", {"request": request,  "myImage": base64_encoded_image})

On client side, you could display the image as follows:

<img src="data:image/jpeg;base64,{{ myImage | safe }}">

Alternative approaches can be found here.

Chris
  • 18,724
  • 6
  • 46
  • 80