Resizing Images Using Nodejs and Imagemagick

Using nodejs and imagemagick, I can resize the image and send it to the browser with this.

var http = require('http'), spawn = require('child_process').spawn; http.createServer(function(req, res) { var image = 'test.jpg'; var convert = spawn('convert', [image, '-resize', '100x100', '-']); convert.stdout.pipe(res); convert.stderr.pipe(process.stderr); }).listen(8080); 

The test image is read from the file system, I want to change it so that the test image is a binary string.

 var image = 'some long binray string representing an image.......'; 

My plan is to store binary strings in Mongodb and read them dynamically.

+4
source share
3 answers

Since you use spawn() to invoke the ImageMagick convert command line, the usual approach is to write intermediate files to a temporary directory where they will be cleaned up either immediately after use or as a schedule task / cron.

If you want to avoid writing a file for conversion, one of the options to try is encoding base64 images using the built-in format . This is similar to how images are encoded in some HTML emails or web pages.

  inline:{base64_file|data:base64_data} Inline images let you read an image defined in a special base64 encoding. 

NOTE. There is a limit on the size of the command line options that you can pass. Imagemagick docs offers 5,000 bytes. Base64 encoded lines are larger than the original (Wikipedia offers an approximate guideline of 137% more ), which can be very limited if you do not show thumbnails.

Another ImageMagick ephemeral format parameter:

  ephemeral:{image_file} Read and then Delete this image file. 

If you want to avoid I / O transfer in general, you'll need a Node.js module that will directly integrate a low-level library such as ImageMagick or GD, rather than wrapping command-line tools.

+3
source

Take a look at the node node-imagemagick module . An example is given on the module page to resize and image and write it to a file ...

 var fs = require('fs'); im.resize({ srcData: fs.readFileSync('kittens.jpg', 'binary'), width: 256 }, function(err, stdout, stderr){ if (err) throw err fs.writeFileSync('kittens-resized.jpg', stdout, 'binary'); console.log('resized kittens.jpg to fit within 256x256px') }); 

You can change this code to do the following ...

 var mime = require('mime') // Get mime type based on file extension. use "npm install mime" , fs = require('fs') , util = require('util') , http = require('http') , im = require('imagemagick'); http.createServer(function (req, res) { var filePath = 'test.jpg'; fs.stat(filePath, function (err, stat) { if (err) { throw err; } fs.readFile(filePath, 'binary', function (err, data) { if (err) { throw err; } im.resize({ srcData: data, width: 256 }, function (err, stdout, stderr) { if (err) { throw err; } res.writeHead(200, { 'Content-Type': mime.lookup(filePath), 'Content-Length': stat.size }); var readStream = fs.createReadStream(filePath); return util.pump(readStream, res); }); }); }); }).listen(8080); 

Ps. Not yet run the code. Let's try to do this soon, but it should give you an idea of ​​how to resize and stream the file asynchronously.

+3
source

What have you tried? You can use GridFS to store image data and receive it as a stream from there. This is in C # .. Not sure if this will help.

 public static void UploadPhoto(string name) { var server = MongoServer.Create("mongodb://localhost:27017"); var database = server.GetDatabase("MyDB"); string fileName = name; using (var fs = new FileStream(fileName, FileMode.Open)) { var gridFsInfo = database.GridFS.Upload(fs, fileName); var fileId = gridFsInfo.Id; //ShowPhoto(filename); } } public static Stream ShowPhoto(string name) { var server = MongoServer.Create("mongodb://localhost:27017"); var database = server.GetDatabase("MyDB"); var file = database.GridFS.FindOne(Query.EQ("filename",name)); var stream = file.OpenRead()) var bytes = new byte[stream.Length]; stream.Read(bytes,0,(int)stream.Length); return stream; } 

Now you can use the stream returned by ShowPhoto.

0
source

All Articles