Della
Della

Reputation: 1614

How to convert a numpy array (which is actually a BGR image) to Base64 string?

I know how to convert an image in the disk to base64 via reading the file. However, in this instance, I already have the image as a numpy array in my program, captured via a camera, like image[:,:,3]. How do I convert it to base64 string such that the image can still be recovered? I tried this.

from base64 import b64encode    
base64.b64encode(image)

It does indeed gives me a string, but when I tested with https://codebeautify.org/base64-to-image-converter, it could not render the image, which means there is something wrong in the conversion. Help please.

I know a solution is to write the image into the disk as a jpg picture and then read it into a base64 string. But obviously, I don't want a file i/o when I can avoid it.

Upvotes: 7

Views: 7557

Answers (2)

ntjess
ntjess

Reputation: 1450

This is a bit more round-about from the other answers, but in case someone else lands here trying to show an image as a Qt base-64 tooltip, the other methods won't work. I had more luck using a QBuffer and QImage:

# Adapted from https://stackoverflow.com/a/34836998/9463643
import qimage2ndarray as q2n

buffer = QtCore.QBuffer()
buffer.open(buffer.WriteOnly)
buffer.seek(0)

img = (np.random.random((100,100))*255).astype('uint8')
img = q2n.array2qimage(img)

img.save(buffer, "PNG", quality=100)
encoded = bytes(buffer.data().toBase64()).decode() # <-- Here's the base 64 image
html = f'<img src="data:image/png;base64,{encoded}">'
element.setToolTip(html)

Upvotes: 0

import random
import random

Reputation: 3245

Here's an example to show what you need to do:

from PIL import Image
import io
import base64
import numpy

# creare a random numpy array of RGB values, 0-255
arr = 255 * numpy.random.rand(20, 20, 3)

im = Image.fromarray(arr.astype("uint8"))
#im.show()  # uncomment to look at the image
rawBytes = io.BytesIO()
im.save(rawBytes, "PNG")
rawBytes.seek(0)  # return to the start of the file
print(base64.b64encode(rawBytes.read()))

I can paste the string printed into the base64 image converter and it'll look similar to im.show(), as the site enlarges the image.

You may need to manipulate your array or provide an appropriate PIL mode when creating your image

Upvotes: 11

Related Questions