sharp icon indicating copy to clipboard operation
sharp copied to clipboard

Feature request: Resize to to Pixel Area Count Limit

Open blowsie opened this issue 9 years ago • 3 comments

It would be great if sharp could scale images to an number of pixels like imagemagick does

Examples here; http://www.imagemagick.org/Usage/resize/#pixel

blowsie avatar May 01 '15 11:05 blowsie

Thanks for the suggestion Sam. I wonder what the algorithm behind it is? Anyone know the internals of *magick well enough to find it?

Taking the longest edge and decrementing it via brute force would probably work, something like the (very much untested):

sharp(image).metadata().then(function(info) {
  var width = info.width;
  var height = info.height;
  while ((width * height) > limit) {
    if (info.width > info.height) {
      width--;
      height = Math.floor(width / info.width * info.height);
    } else {
      height--;
      width = Math.floor(height / info.height * info.width);
    }
  }
  sharp(image).resize(width, height)...
});

As always, very happy to accept a PR implementing this.

lovell avatar May 01 '15 13:05 lovell

This is a solution I am using with for now, not sure exactly how *magick implements it.

var StartWidth  = 800;
var StartHeight = 600;
var TargetArea  = 100000;

var Scalor      = TargetArea / (StartWidth * StartHeight);
var Factor      = Math.sqrt(Scalor);

var EndWidth    = Math.round(StartWidth  * Factor);
var EndHeight   = Math.round(StartHeight * Factor);
var ResultArea  = EndWidth * EndHeight;

var ErrorMargin = ResultArea - TargetArea;

console.log(EndWidth, EndHeight, ResultArea, ErrorMargin);

blowsie avatar May 05 '15 07:05 blowsie

@lovell found it: https://github.com/ImageMagick/ImageMagick/blob/aa413353e3dc86c56a44d23f1d1d4db67e0911ff/MagickCore/geometry.c#L1490

I will try to implement this on weekends. Unless you will know how to do this quickly :)

oaleynik avatar Jan 11 '18 00:01 oaleynik