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://stackoverflow.com/a/7347358/1358670 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://stackoverflow.com/a/6933413/1358670 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.

Community
  • 1
  • 1
Abu Romaïssae
  • 3,841
  • 5
  • 37
  • 59
  • 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'})` – loganfsmyth Mar 27 '14 at 15:01
  • 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 worked – Abu Romaïssae Mar 27 '14 at 15:19
  • Could you upload a tiny jpg and post the base64 in the question along with the PHP version that is working? – loganfsmyth Mar 27 '14 at 15:35
  • Thanks @loganfsmyth for your support, I've found a solution for my problem, please check out my answer – Abu Romaïssae Mar 27 '14 at 17:44
  • 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. – loganfsmyth Mar 27 '14 at 18:53
  • 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` extension – Abu Romaïssae Mar 27 '14 at 22:21

1 Answers1

4

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);
});
Community
  • 1
  • 1
Abu Romaïssae
  • 3,841
  • 5
  • 37
  • 59