Ryan Keenan
Ryan Keenan

Reputation: 331

How to convert Python numpy array to base64 output

I basically need to do this but in Python instead of Javascript. I receive a base64 encoded string from a socketio connection, convert it to uint8 and work on it, then need to convert it to base64 string so I can send it back.

So, up to this point I've got this (I'm getting the data dictionary from the socketio server):

import pickle
import base64
from io import BytesIO
from PIL import Image

base64_image_string = data["image"]
image = Image.open(BytesIO(base64.b64decode(base64_image_string)))
img = np.array(image)

How do I reverse this process to get from img back to base64_image_string?

UPDATE:
I have solved this in the following manner (continuing from the code snippet above):

pil_img = Image.fromarray(img)
buff = BytesIO()
pil_img.save(buff, format="JPEG")
new_image_string = base64.b64encode(buff.getvalue()).decode("utf-8")

Somewhat confusingly, new_image_string is not identical to base64_image_string but the image rendered from new_image_string looks the same so I'm satisfied!

Upvotes: 20

Views: 36119

Answers (3)

Ce Ge
Ce Ge

Reputation: 11

I have the same problem. After some search and try, my final solution is almost the same as yours.

The only difference is that the base64 encoded string is png format data, so I need to change it from RGBA to RGB channels before converted to np.array:

image = image.convert ("RGB")
img = np.array(image)

In the reverse process, you treate the data as JPEG format, maybe this is the reason why new_image_string is not identical to base64_image_string ?

Upvotes: 1

ralf htp
ralf htp

Reputation: 9422

from http://www.programcreek.com/2013/09/convert-image-to-string-in-python/ :

import base64

with open("t.png", "rb") as imageFile:
    str = base64.b64encode(imageFile.read())
    print str

is binary read

https://docs.python.org/2/library/base64.html

Upvotes: -2

juanpa.arrivillaga
juanpa.arrivillaga

Reputation: 95927

I believe since numpy.arrays support the buffer protocol, you just need the following:

processed_string = base64.b64encode(img)

So, for example:

>>> encoded = b"aGVsbG8sIHdvcmxk"
>>> img = np.frombuffer(base64.b64decode(encoded), np.uint8)
>>> img
array([104, 101, 108, 108, 111,  44,  32, 119, 111, 114, 108, 100], dtype=uint8)
>>> img.tobytes()
b'hello, world'
>>> base64.b64encode(img)
b'aGVsbG8sIHdvcmxk'
>>>

Upvotes: 15

Related Questions