Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js Base64 Image decoding and writing to file

I'm sending the contents of this Flex form (Don't ask why) over to node. There is a post paramteter called "photo" which is a base64 encoded image.

Contents of photo get sent over ok. Problem is when I am trying to decode the content and write them to a file.

  var fs = require("fs");

  fs.writeFile("arghhhh.jpg", new Buffer(request.body.photo, "base64").toString(), function(err) {});

I've tried toString("binary") as well. But it seems node doesnt decode all of the content. It seems it only decodes jpg header info and leaves the rest.

Can anyone please help me with this?

Thanks

like image 284
Mehdi Avatar asked Apr 05 '12 23:04

Mehdi


3 Answers

Try removing the .toString() entirely and just write the buffer directly.

like image 149
Nathan Friedly Avatar answered Oct 19 '22 20:10

Nathan Friedly


this is my full solution which would read any base64 image format, decode it and save it in the proper format in the database:

    // Save base64 image to disk
    try
    {
        // Decoding base-64 image
        // Source: http://stackoverflow.com/questions/20267939/nodejs-write-base64-image-file
        function decodeBase64Image(dataString) 
        {
          var matches = dataString.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/);
          var response = {};

          if (matches.length !== 3) 
          {
            return new Error('Invalid input string');
          }

          response.type = matches[1];
          response.data = new Buffer(matches[2], 'base64');

          return response;
        }

        // Regular expression for image type:
        // This regular image extracts the "jpeg" from "image/jpeg"
        var imageTypeRegularExpression      = /\/(.*?)$/;      

        // Generate random string
        var crypto                          = require('crypto');
        var seed                            = crypto.randomBytes(20);
        var uniqueSHA1String                = crypto
                                               .createHash('sha1')
                                                .update(seed)
                                                 .digest('hex');

        var base64Data = 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAZABkAAD/4Q3zaHR0cDovL25zLmFkb2JlLmN...';

        var imageBuffer                      = decodeBase64Image(base64Data);
        var userUploadedFeedMessagesLocation = '../img/upload/feed/';

        var uniqueRandomImageName            = 'image-' + uniqueSHA1String;
        // This variable is actually an array which has 5 values,
        // The [1] value is the real image extension
        var imageTypeDetected                = imageBuffer
                                                .type
                                                 .match(imageTypeRegularExpression);

        var userUploadedImagePath            = userUploadedFeedMessagesLocation + 
                                               uniqueRandomImageName +
                                               '.' + 
                                               imageTypeDetected[1];

        // Save decoded binary image to disk
        try
        {
        require('fs').writeFile(userUploadedImagePath, imageBuffer.data,  
                                function() 
                                {
                                  console.log('DEBUG - feed:message: Saved to disk image attached by user:', userUploadedImagePath);
                                });
        }
        catch(error)
        {
            console.log('ERROR:', error);
        }

    }
    catch(error)
    {
        console.log('ERROR:', error);
    }
like image 44
Placeholder Avatar answered Oct 19 '22 19:10

Placeholder


In nodejs 8.11.3 new Buffer(string, encoding) is deprecated, instead of this the new way to do that is Buffer.from(string, encoding) always without .toString(). For more details read the documentation in nodejs docs: Buffer

like image 2
Diego Alberto Zapata Häntsch Avatar answered Oct 19 '22 20:10

Diego Alberto Zapata Häntsch