0

I have some Python code that generates a dynamic image in PNG format. This works correctly, because I can save the bytes to disk and get a valid PNG image. Then I try to encode the bytes in base64 and pass them to an HTML template (in a Django website) to get the image rendered. This can be done, because I can get it to work if I pass a base64 string that is known to be correct. But it does not work with my string, probably because I am not doing the base64 encoding correctly. What am I doing wrong?

buf = io.BytesIO()
plt.savefig(buf, format='png') # an image generated by a plotting library
plt.close(f)
# This produces a valid PNG image
file_path = os.path.join(module_dir, 'image1.png')
buf.seek(0)
buf_bytes = buf.read()
with open(file_path, 'wb') as output:
    output.write(buf_bytes)
# This is a valid base64 encoding of a small image, from Wikipedia
red_dot = "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="

# This works, i.e. the page displays a tiny red dot
return render(request, 'graph.html', {'graph1b64': red_dot})
# This does not work; the page displays the image alternate text
#return render(request, 'graph.html', {'graph1b64': base64.b64encode(buf_bytes)})
# This probably means I am not doing the base64 encoding correctly

# This is what is in the 'graph.html' template
#<div class="graph1">
#     <img src="data:image/png;base64, {{ graph1b64 }}" alt="graph1 in base64" />
#</div>
radumanolescu
  • 4,059
  • 2
  • 31
  • 44
  • Does [this](https://stackoverflow.com/questions/8908287/why-do-i-need-b-to-encode-a-string-with-base64) article help? – Diggy. May 12 '20 at 18:30
  • Think you're doing everything right with Base64. Only difference I can see is `red_dot` is a string whereas `b64encode` returns a bytes object. Perhaps try `{'graph1b64': base64.b64encode(buf_bytes).decode()}`? – MarkM May 12 '20 at 18:32
  • 1
    @Diggy.: I don't think so. They start with a string, some text, probably represented with two bytes per char - so they need to transform it to bytes. In my case, I already have bytes, because these are the same bytes I can save to disk to get a PNG image. – radumanolescu May 12 '20 at 18:34
  • `b64encode` returns bytes, `.decode()` those first – Marco Bonelli May 12 '20 at 18:36
  • @MarkM: Please write it as an answer, so I can accept your solution - and thank you! – radumanolescu May 12 '20 at 18:38

1 Answers1

1

red_dot is a string whereas b64encode returns a bytes object. It should work with {'graph1b64': base64.b64encode(buf_bytes).decode()}.

MarkM
  • 798
  • 6
  • 17