11

I have found posts that are close to what I'm looking for, but I have not been able to successfully implement what I want. Here is the general flow:

  1. Submit photo with rest of venue data, as base64 data
  2. Strip data prefix if it exists, so I have just the image base64 data

var base64data = venue.image.replace(/^data:image\/png;base64,|^data:image\/jpeg;base64,|^data:image\/jpg;base64,|^data:image\/bmp;base64,/, '');

  1. Store Base64 data in GridFS via MongoDB (I'm using gridfstore)
  2. Then, I'd like to retrieve the image upon request as a raw image file via a URL.

// generic images route
server.get(version+'/images/:id', function(req, res) {
  gridfstore.read( req.params.id, function(error,data) {
    res.writeHead(200, {
      'Content-Type': 'image/jpeg',
      'Content-Length': data.buffer.length
    });

    res.end(data.buffer);
  });
});

Basically, this method returns the Base64 bytes stored in GridFS. I have tried other methods but they don't return the raw image.

I'd like to pull up the image using URLs like this:

http://[localhost]/1/images/11dbcef0-257b-11e3-97d7-cbbea10abbcb

Here is a screenshot of the browser trace: browser trace

hexacyanide
  • 88,222
  • 31
  • 159
  • 162
remotevision
  • 433
  • 1
  • 6
  • 14

2 Answers2

16

You can take the string from MongoDB, create a new buffer instance, and specify an encoding when doing so. The resultant buffer will be in binary data.

var b64str = /* whatever you fetched from the database */;
var buf = Buffer.from(b64str, 'base64');

So in your implementation:

server.get(version+'/images/:id', function(req, res) {
  gridfstore.read(req.params.id, function(err, data) {
    var img = Buffer.from(data.buffer, 'base64');

    res.writeHead(200, {
      'Content-Type': 'image/jpeg',
      'Content-Length': img.length
    });
    res.end(img); 

  });
});
Paolo Moretti
  • 54,162
  • 23
  • 101
  • 92
hexacyanide
  • 88,222
  • 31
  • 159
  • 162
  • thanks @hexacyanide, I tried what you suggested but it is coming back as an invalid image. The buffer is accurately allocated and the length is accurate but the image just doesn't display, so I'll do a little more digging and see if I can provide additional information. When I take the Base64 data URI, and display it in the HTML page with it works, so at least I know the Base64 is valid. – remotevision Sep 25 '13 at 13:18
  • So what are you trying to do? Are you trying to just display the image on a page? – hexacyanide Sep 25 '13 at 14:16
  • I'm trying to simply return the image, just like you would call http://[somehost]/someimage.jpg. I have attached a screenshot if it helps at all. With the code you suggested, the browser just clocks. Also, I am using Restify on the server but from what I have read, it supports Node.js ServerResponse. http://mcavage.me/node-restify/#Content-Negotiation – remotevision Sep 25 '13 at 14:43
  • and for what it is worth, this is what I see for the data in GridFS. "data" : BinData(0,"ZGF0YTppbWFnZS9qcGVnO2Jhc2U2NCwvOWovNEFBUVNrWkpSZ0FCQWdB... – remotevision Sep 25 '13 at 14:53
  • What do you mean the browser just clocks? Does the `res.end()` fail to work? This doesn't make much sense if embedding the image with HTML works fine. – hexacyanide Sep 25 '13 at 14:58
  • I have created 2 gists. One that works, where you'll see I am adding the tags in the response. So, the buffer still contains Base64 encoded data for the image. https://gist.github.com/remotevision/6708240 – remotevision Sep 26 '13 at 01:24
  • 1
    ARGH!! the image was Base64 encoded when I stored it in GridFS, so it was double-encoded. Now I am storing a single-encoded image and everything is working. whew! thanks for your help – remotevision Sep 26 '13 at 01:36
  • Works great. Also, don't use a post request to get images in binary. I was going in circles until I realized this. – shash7 Jun 03 '14 at 16:05
  • How would you specify the name of the file before sending? – Brant May 03 '17 at 14:31
0

Make sure your string is correct. This worked for me..

var buf = new Buffer(b64stringhere, 'base64');
var express = require('express'), app = express();
app.get('/img', function(r, s){
    s.end(buf);
})
app.listen(80);
C B
  • 12,482
  • 5
  • 36
  • 48