Skip to content

Instantly share code, notes, and snippets.

@jfsiii
Created September 6, 2012 01:12
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save jfsiii/3649429 to your computer and use it in GitHub Desktop.
Save jfsiii/3649429 to your computer and use it in GitHub Desktop.
Convert a remote image to Base64-encoded string
// Uses [request](https://github.com/mikeal/request)
// /?url=http://nodejs.org/logo.png
// /?uri=http://nodejs.org/logo.png
// /?url=http://nodejs.org/logo.png&cb=cbName
// /?url=http://nodejs.org/logo.png&callback=cbName
var fs = require('fs');
var url = require('url');
var http = require('http');
var request = require('request');
var port = 8888;
var server = http.createServer(function requestListener(httpRequest, httpResponse) {
var params = url.parse(httpRequest.url, true).query;
var imageURL = params.url || params.uri || params.image;
var callbackName = params.callback || params.cb || '';
if (!imageURL) return httpResponse.end();
request(
{url: imageURL, encoding: 'binary'},
function onImageResponse(error, imageResponse, imageBody) {
if (error) throw error;
var imageType = imageResponse.headers['content-type'];
var base64 = new Buffer(imageBody, 'binary').toString('base64');
var dataURI = 'data:' + imageType + ';base64,' + base64;
var jsonString = JSON.stringify({
code: imageResponse.statusCode,
desc: http.STATUS_CODES[imageResponse.statusCode],
type: imageType,
orig: imageURL,
data: dataURI
});
var jsonpString = callbackName + '(' + jsonString + ')';
var payload = callbackName ? jsonpString : jsonString;
httpResponse.writeHead(imageResponse.statusCode, {'Content-Type': 'application/json'});
httpResponse.write(payload);
httpResponse.end();
}
);
});
server.listen(port);
console.log('base64 server created and listening on port', port);
@jfsiii
Copy link
Author

jfsiii commented Sep 6, 2012

I'd love to use pipes and avoid the .on('data' accumulator, but I don't think that's possible.

@jfsiii
Copy link
Author

jfsiii commented Sep 6, 2012

@maxogden suggested:

require('request')('imageurl', function(e,r,b){ // b is image data })

but a) I think request is doing the same .on('data' accumulator b) I can't cast the buffer to the correct base64 string

I say that having tried this, which failed:

require('request')('http://nodejs.org/logo.png', function (e,r,b) {
  var type    = r.headers["content-type"];
  var prefix  = "data:" + type + ";base64,";
  var base64  = new Buffer(b).toString('base64');
  var dataURI = prefix + base64;

  console.log(dataURI);
});

It works as expected when I set encoding to binary

require('request')(
  {
    url: 'http://nodejs.org/logo.png', 
    encoding: 'binary'
  }
  , function (e,r,b) {
    var type    = r.headers["content-type"];
    var prefix  = "data:" + type + ";base64,";
    var base64  = new Buffer(b, 'binary').toString('base64');
    var dataURI = prefix + base64;

    console.log(dataURI);
  }
);

I don't mind needing to specify the encoding, I just want to make sure it's required and I'm not, say, casting the Buffer incorrectly.

@Syldel
Copy link

Syldel commented Nov 4, 2016

OK ! I set the encoding to 'binary' and it works ! Thank you ! ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment