4

I've been able to successfully write binary data (an image) to MongoDB in Node.js. However I can't find clear documentation on how to read it back.

Here's how I'm writing the image to MongoDB:

var imageFile = req.files.myFile;
var imageData = fs.readFileSync(imageFile.path);

var imageBson = {};
imageBson.image = new db.bson_serializer.Binary(imageData);
imageBson.imageType = imageFile.type;

db.collection('images').insert(imageBson, {safe: true},function(err, data) {

I'd appreciate any pointers on reading the image from Mongo using Node. I'm assuming there's a function like "db.bson_deserializer...". Thanks!

2 Answers 2

4

Found the answer:

        var imageFile = req.files.myFile;
    fs.exists(imageFile.path, function(exists)  {

        if(exists)
        {
            console.log("File uploaded: " + util.inspect(imageFile));
            fs.readFile(imageFile.path, function(err, imageData) {
                if (err) {
                    res.end("Error reading your file on the server!");
                }else{
                    //when saving an object with an image's byte array
                    var imageBson = {};
                    //var imageData = fs.readFileSync(imageFile.path);
                    imageBson.image = new req.mongo.Binary(imageData);
                    imageBson.imageType = imageFile.mimetype;
console.log("imageBson: " + util.inspect(imageBson));

                    req.imagesCollection.insert(imageBson, {safe: true},function(err, bsonData) {

                        if (err) {
                            res.end({ msg:'Error saving your file to the database!' });
                        }else{
                            fs.unlink(imageFile.path); // Deletes the file from the local disk
                            var imageBson = bsonData[0];
                            var imageId = imageBson._id;
                            res.redirect('images/' + imageId);
                        }
                    });
                }
            });
        } else {
            res.end("Oddly your file was uploaded but doesn't seem to exist!\n" + util.inspect(imageFile));
        }
    });
Sign up to request clarification or add additional context in comments.

1 Comment

whoah, nearly a year later ;D
0

The MongoDB part isn't complicated. Once a Buffer is in the model, just let the db save it. MongoDB converts that into BinData. 80% of this code is just getting an image into and out of a PNG file.

People say don't store images in MongoDB, but icons/thumbs are tiny. Having said that, it might be a good idea to have an icons collection and only store them once using a hash of the image data as the _id.

model class example

class MyModel {
    _icon: Buffer
    get icon(): Buffer {
        return this._icon
    }
    set icon(value: Buffer) {
        this._icon = value
    }
}

image helper

static async loadImage(url: string) {
    var files = require('../lib/files')
    var buffer = await files.urlContents(url, true)
    return buffer
}

static async saveImage(image: Buffer, path: string) {
    var files = require('../lib/files')
    files.write(path, image.buffer)
    return path
}

files helper

function urlResponse(url, binary) {
    var request = require("request")
    if (binary)
        request = request.defaults({ encoding: null })
    return new Promise(function (resolve, reject) {
        request(url, function (error, res, body) {
            if (error || res.statusCode !== 200 || body.includes('Incomplete response received from application'))
                resolve({ statusCode: res?.statusCode !== 200 ? (res?.statusCode || 500) : 500 });
            else
                resolve(res);
        });
    });
}

async function urlContents(url, binary) {
    var res = await urlResponse(url, binary)
    if (binary)
        return Buffer.from(res.body)
    else
        return res.body
}


function write(fileName, contents) {
    fs.writeFileSync(fileName, contents)
}

mongodb helper

// ...saving

myModel.icon = loadImage('http://some.site.com/image.png')
collection.insertOne(myModel)

// ..getting
myModel = collection.findOne(query) // now myModel contains icon
saveImage(myModel.icon, '/home/toddmo/pictures/wow.png')

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.