aheckmann / gm

GraphicsMagick for node
http://aheckmann.github.com/gm/
6.96k stars 614 forks source link

Using ImageMagick Crop fails to remove unused pixels #501

Open crockpotveggies opened 8 years ago

crockpotveggies commented 8 years ago

Mirror for a StackOverflow question I opened: http://stackoverflow.com/questions/35471083/node-js-gm-package-crops-but-does-not-fit-to-pixels


I'm having an issue where I crop the image but all it does is remove the cropped pixel data and leaves a bunch of padding in the image. Here's the result:

weird crop

Code is below. Is this my own failure or a bug in gm or ImageMagick?

Here's the code I'm using, it's part of a face detection loop:

var faceDetect = require('face-detect');
var fs = require('fs');
var Canvas = require('canvas');
var gm = require('gm').subClass({imageMagick: true});;

// initialize the line reader from a file name
var outputPath = 'faces/';
var fileList = 'imagelist.txt';
var lineReader = require('readline').createInterface({
  input: require('fs').createReadStream(fileList)
});

lineReader.on('line', function (fileName) {
  console.log('Reading file '+fileName);

  fs.readFile(fileName, function(err, data) {
    if (err) throw err;
    var img = new Canvas.Image; // Create a new Image

    img.dataMode = Canvas.Image.MODE_MIME | Canvas.Image.MODE_IMAGE;

    img.onerror = function(error) {
        console.log(error);
    }

    img.onload = function() {
      console.log('Processing image...', img.width, img.height)

      // Initialiaze a new Canvas with the same dimensions
      // as the image, and get a 2D drawing context for it.
      var canvas = new Canvas(img.width, img.height);
      var ctx = canvas.getContext('2d');
      ctx.drawImage(img, 0, 0, img.width, img.height);

      // now that the image is loaded, we extract faces
      var result = faceDetect.detect_objects({ 
        canvas : canvas,
        interval : 5,
        min_neighbors : 1 
      });

      console.log('Found ' + result.length  + ' faces.');

      // for each face, crop and output
      for (var i = 0; i < result.length; i++){
        var face =  result[i];

        var els = fileName.split('/');
        var dest = outputPath+els[els.length-1].replace('.gif','_'+i.toString()+'.gif');

        console.log('Attempting to resize image to '+dest);

        gm(fileName)
          .crop(face.width, face.height, face.x, face.y)
          .write(dest, function (err) {
            if (!err) console.log('Wrote image to '+dest);
          });
      }
    }

    // load the image (will trigger onload)
    img.src = data;
  }); 
});
elyngved commented 6 years ago

@crockpotveggies I'm trying the same thing - were you able to figure it out?

elyngved commented 6 years ago

Figured this out by chaining .repage('+') after the crop() invocation