Search code examples
javascriptnode.jsimagemagickstdoutgraphicsmagick

How to check for corrupted jpg images using node.js and gm?


I'd like to check for corrupted jpeg images and so far, straight in the command line I can use identify image.jpg which outputs:

image.jpg JPEG 1920x1200 1920x1200+0+0 8-bit sRGB 65.5KB 0.000u 0:00.009
identify: Premature end of JPEG file `image.jpg' @ warning/jpeg.c/JPEGWarningHandler/352.
identify: Corrupt JPEG data: premature end of data segment `image.jpg' @ warning/jpeg.c/JPEGWarningHandler/352.

or gm identify image.jpg which outputs:

image.jpg JPEG 1920x1200+0+0 DirectClass 8-bit 64.0Ki 0.000u 0:01
gm identify: Corrupt JPEG data: premature end of data segment (image.jpg).
    gm identify: Corrupt JPEG data: premature end of data segment (image.jpg).

It would be nice if I can use the gm package to get the corrupt JPEG data too. Simply using identify() outputs a lot of data, but nothing about corrupt data

gm('image.jpg')
.identify('%C',function (err, data) {
  if (!err) console.log(data)
  else console.error(err)
});

I've noticed this note in the readme:

If gm does not supply you with a method you need or does not work as you'd like, you can simply use gm().in() or gm().out() to set your own arguments.

I've tried something like this:

gm()
.command("identify") 
.in('image.jpg');

but I get no output so I'm probably doing it wrong.

I've also tried node-cmd:

cmd.get(
        'gm identify image.jpg',
        function(data){
            console.log('output: ',data)
        }
    );

but I only see the first line of the output.

What's the clean/recommended way of getting the multiline output from identify via gm package ? Otherwise, what's a node elegant solution to reading the full output of the identify command.

Update My guess is the string isn't displayed using gm because it comes through stderr, not stdout.

I've tested using a tweaked version of this snippet:

var spawn = require('child_process').spawn;

var bin = "identify"
var args = ['image.jpg'];
var cspr = spawn(bin, args);
cspr.stderr.on('data', function (data) {
    data += '';
    console.log(data.replace("\n", "\nstderr: "));
});
cspr.on('exit', function (code) {
    console.log('child process exited with code ' + code);
    process.exit(code);
});

What's the clean way of getting the stderr output via gm ?


Solution

  • I am very unqualified to say anything much about node or Javascript, but the following idea may get you up and running.

    As I understand it, you want to use identify but are unable to capture its stderr. We do know how to capture the stderr of convert though. So, the suggestion is to invoke convert in a way it mimics the functionality of identify but with the calling interface of convert.

    You can do that like this:

    gm convert someImage.jpg info:-
    

    optionally adding in -verbose if needed.

    That looks like this in node apparently!

    gm(jpgPath)
      .command('convert')
      .write('out.png', function(err, stdout,stderr){   
         console.log("stderr",stderr);
    });