Can't read Base64 encoded image in Node.js which is sent from Python

I’m trying to achieve communication between Node.js and Python. For this task, I’m using Node.js’s python-shell NPM module to run a Python script and read the print output. I want to do some OpenCV image processing stuff on Python, send the image to Node.js and serve it on an application.

Here is the Node.js part:

let {PythonShell} = require('python-shell')

let options = {
  mode: 'text',
  pythonOptions: ['-u'], // get print results in real-time
  args: ['value1', 'value2', 'value3']
};

PythonShell.run('engine.py', options, function (err, results) {
  if (err) throw err;
  // results is an array consisting of messages collected during execution
/*   var fs = require("fs");

  fs.writeFile("arghhhh.jpeg", Buffer.from(results, "base64"), function(err) {}); */
  console.log(results.toString())
});

Here is the Python part:

from PIL import Image
import cv2 as cv2
import base64

source = cv2.imread("60_3.tif", cv2.IMREAD_GRAYSCALE)
# tried making it a PIL image but didn't change anything
# source = Image.fromarray(source)
print(base64.b64encode(source))

Everything looks good in theory, however, I tried to write the image on Node.js side and I can’t open the image. Also checked sizes of the both strings and there was 3 character difference on Node.js side.
Do I need to do something else in between to share a simple image between two languages?

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

import cv2 as cv2
import base64

source = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
success, encoded_image = cv2.imencode('.png', source)
content = encoded_image.tobytes()
print(base64.b64encode(content).decode('ascii'))

This is how I figured it out. Encoding image with OpenCV’s imencode method and converting it to bytes with .tobytes() is curial. Also, the image as bytes needs to be encoded and decoded as ‘ascii’ to be read on the NodeJS part.

Solution 2

You’re most probably running your script with python 2, but the library you’re using is using python3, and your string will look something like b'aGVsbG8=' instead of aGVsbG8=.

Try running from your shell

python3 engine.py

Solution 3

python code # cv.py

import cv2 as cv2
import base64

source = cv2.imread('0.png', cv2.IMREAD_GRAYSCALE)
success, encoded_image = cv2.imencode('.png', source)
content = encoded_image.tobytes()
print(base64.b64encode(content).decode('ascii'))

nodejs code

const spawn = require('child_process').spawn;
const fs = require('fs');

const process = spawn('python', ['./cv.py']);

process.stdout.on('data', data => {
  console.log(data.toString()); 
  fs.writeFile("test.png", Buffer.from(data.toString(), "base64"), function(err) {});
});

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply