NeilS
NeilS

Reputation: 43

Encoding an opencv image into Base64 doesn't produce a valid image

I am trying to send a picture from my Pi camera to a flask web server. When I encode the image Base64 it doesn't seem to produce a valid image.

I can take the picture and process it through opencv. The Base64 encoded image is passed to the web page, but the string sent is not a valid image. To prove this I have saved the image and processed it with an online Base64 converter. Pasting this string into the web page shows the image.

def Take_Picture(camera):
    stream = io.BytesIO()                                           # saving the picture to an in-program stream 
    camera.resolution = (160,120)                                   # set resolution
    camera.capture(stream, format='jpeg', use_video_port=True)      # capture into stream
    mydata = np.fromstring(stream.getvalue(), dtype=np.uint8)       # convert image into numpy array
    img = cv2.imdecode(mydata, -1)                                  # to opencv image
    data = base64.b64encode(img).decode('utf-8')
    print(data)
    cv2.imwrite("test.jpg",img)
    return data

HTML

<img src="data:image/jpeg;charset=utf-8;base64,{{img}}"  alt="Camera View" width="640" height="480">

I get a result of

b'AAIAAAIAAAIAAAIAAAIAAAIAAAIAAAIAAAIAAAIAAAIAAAMAAAIAAAIAAA...

from data above. But I get

/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAIBAQEBAQIBAQECAgICAgQDAgICAgUEBAMEBgUG...

from test.jpg from an online Base64 conversion. Putting this string in the web page displays the image.

Upvotes: 4

Views: 9351

Answers (2)

Simon Buus Jensen
Simon Buus Jensen

Reputation: 165

The following solved it for me:

import cv2
import base64

# img is a numpy array / opencv image
_, encoded_img = cv2.imencode('.png', img)  # Works for '.jpg' as well
base64_img = base64.b64encode(encoded_img).decode("utf-8")

Upvotes: 2

Peshmerge
Peshmerge

Reputation: 1060

You have to convert you image back from a numpy array to an image which can then encoded correctly to Base64! What you now do is you encode a numpy array to base64 string which surely can't give the same result the online base64 tool gives!

What you need to do, pass your numpy array to cv2.imencode which returns a buffer image object and then you can convert it to base64

retval, buffer_img= cv2.imencode('.jpg', img)
data = base64.b64encode(buffer_img)

OR you can skip the img = cv2.imdecode(mydata, -1) and pass mydata directly to base64.b64encode(mydata) while the image is already stored the memory!

There is no openCV image, the openCV image is a ndArray. When you execute print(type(img)) you will get <class 'numpy.ndarray'>

Upvotes: 7

Related Questions