30

Currently I handle image uploads using angular-file-upload and I simply save the image to the server's file system and reference it in the HTML. However, I want to try and store the image directly in the database within the Schema I defined for my blog posts.

var blogSchema = new Schema({
    title: String,
    author: String,
    body: String,
    likes: { type: Number, default: 0 },
    comments: [{ type: Schema.Types.ObjectId, ref: 'Comment' }],
    date: { type: Date, default: Date.now },
    imageURL: String   // instead of this

    image: // store it directly
});

"imageURL: String" stores the path to the image.

I want to make it so that I can just have a field that stores the image itself. I was thinking that I could perhaps just upload the image like I already do, but instead convert the image after it has been uploaded and store it in binary (or some other form) in Mongo. Is this possible?

Thanks!

Bryan Cho
  • 303
  • 1
  • 4
  • 4

3 Answers3

34

This example below shows how to upload an image to MongoDB using mongoose. Click this link for the original source

var express = require('express');
var fs = require('fs');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var imgPath = '/path/yourimage.png';

mongoose.connect('localhost', 'testing_storeImg');

var schema = new Schema({
    img: { data: Buffer, contentType: String }
});

var A = mongoose.model('A', schema);

mongoose.connection.on('open', function () {
  console.error('mongo is open');

  A.remove(function (err) {
    if (err) throw err;

    console.error('removed old docs');

    // store an img in binary in mongo
    var a = new A;
    a.img.data = fs.readFileSync(imgPath);
    a.img.contentType = 'image/png';
    a.save(function (err, a) {
      if (err) throw err;

      console.error('saved img to mongo');

      // start a demo server
      var server = express.createServer();
      server.get('/', function (req, res, next) {
        A.findById(a, function (err, doc) {
          if (err) return next(err);
          res.contentType(doc.img.contentType);
          res.send(doc.img.data);
        });
      });

      server.on('close', function () {
        console.error('dropping db');
        mongoose.connection.db.dropDatabase(function () {
          console.error('closing db connection');
          mongoose.connection.close();
        });
      });

      server.listen(3333, function (err) {
        var address = server.address();
        console.error('server listening on http://%s:%d', address.address, address.port);
        console.error('press CTRL+C to exit');
      });

      process.on('SIGINT', function () {
        server.close();
      });
    });
  });

});
Alex
  • 21,273
  • 10
  • 61
  • 73
  • 4
    Thanks for your answer! I was able to save the file to the database using that. Do you know how I could load the images on the client side using Angular? – Bryan Cho Apr 21 '15 at 21:58
  • @Jaco How to get the image's path automatically after chose an image from File Manager ? – ridoansaleh Aug 07 '17 at 01:53
  • @BryanCho You can encode the data taken from the document using fromCharCode & btoa and then assign it to the image’s source. E.g. `src = "data:image/png;base64," + btoa(String.fromCharCode.apply(null, img.data))` – David Streid Dec 14 '18 at 12:01
0
router.get("/:i", function (req, res) {
    
   var dataGet = {_id: req.params.i}
    
   fileModel.findOne(dataGet).exec(function (err, doc) {

        if (err) {
            return next(err)
        }
    
        var base64dataa = new Buffer(doc.fileData,'binary').toString('base64');
    
        var ress = {
           fileData: base64dataa,
           mime: doc.mimeType,
           name: doc.fileName
        }

       // res.json(ress)
       res.contentType('image/jpeg')
       res.send(doc.fileData)
   })
})  
        
    
    
router.post('/display/', function (req, res) {

       var data = {
           file: req.body.fileData,
           mime: req.body.mime,
           name: req.body.name
       }
    
       res.json(data)
})
Mureinik
  • 297,002
  • 52
  • 306
  • 350
0

This is code which save data into mongodb. data is binary. I can display this 'image/jpg,base64,{{data}}' but I don't understand how can I display base64data.

file.on('data', function (data) {
            buffer += data;

            var file = new fileModel({
                fileData: data
            })

var Busboy = require('busboy');

router.post('/upload', function (req, res) {

    var busboy = new Busboy({headers: req.headers});
    var base64data = "";
    var filetype = "";
    var name = "";
    var argum = [];
    var data2

    busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {

        var buffer = "";
        filetype = mimetype;
        name = filename;


        // file.setEncoding('base64');


        file.on('data', function (data) {
            buffer += data;

            var file = new fileModel({
                fileData: data
            })
            //
            file.save(function (err, file) {
                if (err) {
                    return next(err)
                }
                // res.json(201, newData)
                // console.log("Save in database" + file.desc)
            })
        });
        file.on('end', function () {
            base64data = buffer;
        });
    });


    busboy.on('field', function (fieldname, val, fieldnameTruncated, valTruncated) {

        argum.push(val);
    });
    busboy.on('finish', function () {
        var base64dataa = new Buffer(base64data, 'binary').toString('base64');
        res.json(base64dataa)
        var jsonBin = {
            base64data_: base64data, mime_: filetype, name_: name,
            owner_: argum[0], description_: argum[1]
        }

        // res.json(jsonBin)

        var file = new fileModel({
            fileData: jsonBin.base64data,
            mimeType: jsonBin.mime_,
            fileName: jsonBin.name_,
            fileOwner: jsonBin.owner_,
            desc: jsonBin.description_
        })
        //
        file.save(function (err, file) {
            if (err) {
                return next(err)
            }
            // res.json(201, newData)
            console.log("Save in database" + file.desc)
        })
    });

    req.pipe(busboy);
});
YakovL
  • 7,557
  • 12
  • 62
  • 102
  • The "I can this display 'image/jpg,base64,{{data}}' but I don't understand how can I display base64data" sentence has a missing verb, I guess. If I'm correct, please add it. – YakovL Jul 13 '16 at 22:13
  • data is variable with binary data. I can this display as 'image/jpg,base64, but base64data is diffrent than data. I can't even display it. – Krzysztof Sikora Jul 14 '16 at 08:26