Creating image from base64 string in NodeJS
Asked Answered
G

1

8

I am trying to upload an image that I extract from a my canvas and post via ajax, and I have trouble creating the image file on my server side.

I have following this answer: https://mcmap.net/q/1471183/-how-to-write-binary-data-to-a-file-using-node-js but still I seem to miss something here or there.

Here is my javascript (browser) code:

var img = myCanvas.toDataURL("image/jpeg");

// ajax request to send the image

and in server side, I do the following:

var fd =  fs.openSync('./img.jpeg', 'w');
req.body.image = req.body.image.replace(/^data:image\/\w+;base64,/, "");
console.log( req.body.image );

var buff = new Buffer(req.body.image, 'base64');
fs.write(fd, buff, 0, buff.length, 0, function(err,written){
    console.log( ">> "+ err );
    fs.closeSync( fd );
});

As you can see, I've logged the image to see if it was properly sent, and IT IS, but still I can't open the created img.jpeg file

any help or hint is very welcome.


EDIT

I've also tried the solution in here: https://mcmap.net/q/116563/-how-can-i-save-a-base64-encoded-image-to-disk but I still have the same problem


EDIT:2

I've tested my front-end side, with a PHP script in the server side, and the image produced was very good, so I would conclude that the problem is in my NodeJS code.

Guibert answered 27/3, 2014 at 12:40 Comment(6)
Nothing immediately jumps out at me, but have you compared the files from PHP vs Node to see if there is a noticable difference? Different length, different data? Also, a simpler method: fs.writeFileSync('./img.jpeg', req.body.image.replace(/^data:image\/\w+;base64,/, ""), {encoding: 'base64'})Verulamium
Yeah, I've tried the simpler method you specified, also I got my base64 code in NodeJS, wrote it in a text file, then used the exact string from the text file in my PHP script, and it workedHypnoanalysis
Could you upload a tiny jpg and post the base64 in the question along with the PHP version that is working?Verulamium
Thanks @Verulamium for your support, I've found a solution for my problem, please check out my answerHypnoanalysis
Nice, glad you figured it out. Can I ask what you are using to populate req.body.image? Are you using the express bodyParser? How are you populating the POST data client-side? Base64 does not treat spaces as pluses, but that conversion could be getting introduced elsewhere.Verulamium
in the front end all I did was getting the image from myCanvas and send it via ajax post query nothing special not even using jQuery, and in node JS I'm using the body parser of the connect extensionHypnoanalysis
G
5

The problem was in the treatment on NodeJS, and I didn't doubt the code since it was the same every where with people commenting that its worked for them, nothing were different so I didn't doubt the process, but either something done wrong.

When checking it in my PHP script I've found a step that is not in the NodeJS code, and here is the PHP code:

$img = $_POST[ 'image' ];

$img = str_replace('data:image/jpeg;base64,', '', $img);
$img = str_replace(' ', '+', $img);

$data = base64_decode($img);
$file = "./". uniqid() . '.png';
$success = file_put_contents($file, $data);
print $success ? $file : 'Unable to save the file.';

The difference is here: str_replace(' ', '+', $img);

I don't know how it worked for others, but for me replacing EVERY space in the base64 by + solved my problem.


New NodeJS code

req.body.image = req.body.image.replace(/^data:image\/\w+;base64,/, "");
req.body.image = req.body.image.replace(/ /g, '+');
console.log( req.body.image );

var buff = new Buffer(req.body.image, 'base64');
fs.write(fd, buff, 0, buff.length, 0, function(err,written){
    console.log( ">> "+ err );
    fs.closeSync( fd );
});

I hope this will help someone else


A better version of the code:

req.body.image = req.body.image.replace(/^data:image\/jpeg+;base64,/, "");
req.body.image = req.body.image.replace(/ /g, '+');

fs.writeFile('./records/'+model+'/out.jpeg', req.body.image, 'base64', function(err) {
    console.log(err);
});
Guibert answered 27/3, 2014 at 17:51 Comment(1)
Thank you, I had the same issue with a base64 image from iOS to NodeJS.Pentahedron

© 2022 - 2024 — McMap. All rights reserved.