Skip to content

Instantly share code, notes, and snippets.

@chrisjhoughton
Last active January 9, 2021 05:19
Show Gist options
  • Save chrisjhoughton/ce73112b59551f8f080d to your computer and use it in GitHub Desktop.
Save chrisjhoughton/ce73112b59551f8f080d to your computer and use it in GitHub Desktop.

Revisions

  1. chrisjhoughton revised this gist Sep 12, 2014. 1 changed file with 8 additions and 0 deletions.
    8 changes: 8 additions & 0 deletions crop-resize.js
    Original file line number Diff line number Diff line change
    @@ -77,6 +77,14 @@ module.exports = function (url, requiredWidth, requiredHeight) {
    cropX = 0;
    cropY = (actualSize.height - cropHeight) / 2;
    }

    // we're already the correct ratio
    else {
    cropWidth = 0;
    cropHeight = 0;
    cropX = 0;
    cropY = 0;
    }

    // Crop and resize
    im(url)
  2. chrisjhoughton revised this gist Sep 11, 2014. 1 changed file with 6 additions and 0 deletions.
    6 changes: 6 additions & 0 deletions crop-resize.js
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,9 @@
    /*
    * Given an image URL or path, crop and resize it to be exactly a specific size.
    * Crops centrally to force enforce the correct aspect ratio, and then resizes as per normal.
    * Depends on the `when` and `gm` NPM modules.
    * Returns a promise that resolves with an image buffer in a .PNG format.
    */
    var when = require('when');
    var gm = require('gm');
    var im = gm.subClass({ imageMagick: true }); // use `im` in place of `gm` for heroku compatibility
  3. chrisjhoughton revised this gist Sep 11, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion crop-resize.js
    Original file line number Diff line number Diff line change
    @@ -86,5 +86,5 @@ module.exports = function (url, requiredWidth, requiredHeight) {

    });

    }.bind(this));
    });
    };
  4. chrisjhoughton created this gist Sep 11, 2014.
    90 changes: 90 additions & 0 deletions crop-resize.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,90 @@
    var when = require('when');
    var gm = require('gm');
    var im = gm.subClass({ imageMagick: true }); // use `im` in place of `gm` for heroku compatibility

    /*
    * Get the size of an image
    */
    var getImageSize = function (file) {
    return when.promise(function (resolve, reject) {

    im(file).size(function (err, size) {
    if (err) {
    reject(err);
    } else {
    resolve(size);
    }
    });

    });
    };


    /*
    * Crop and resize an image to precisely the correct dimensions.
    * Crops first to get to the correct aspect ratio, and then resizes
    * accordingly.
    *
    * Works with either a URL, or a path.
    */
    module.exports = function (url, requiredWidth, requiredHeight) {
    return when.promise(function (resolve, reject) {

    // We need to resize and then crop. These dimensions
    // help us choose how to do this.
    var requiredRatio = requiredWidth / requiredHeight;

    // Get the size of the image
    getImageSize(url)

    // Crop to required dimensions and then resize
    .then(function (actualSize) {

    // If the actual width or height are too small, then reject
    if (actualSize.width < requiredWidth || actualSize.height < requiredHeight) {
    reject('image_too_small');
    return;
    }

    var actualRatio = actualSize.width / actualSize.height;

    // dimensions we'll crop to
    var cropWidth;
    var cropHeight;

    // crop co-ordinates (top left)
    var cropX;
    var cropY;

    // If actual ratio is too high, we need to crop the width
    if (actualRatio > requiredRatio) {
    cropWidth = actualSize.height * requiredRatio;
    cropHeight = actualSize.height; // no change
    cropX = (actualSize.width - cropWidth) / 2
    cropY = 0;
    }

    // If actual ratio is too low, we need to crop the height
    else if (actualRatio < requiredRatio) {
    cropWidth = actualSize.width
    cropHeight = actualSize.width / requiredRatio; // no change
    cropX = 0;
    cropY = (actualSize.height - cropHeight) / 2;
    }

    // Crop and resize
    im(url)
    .crop(cropWidth, cropHeight, cropX, cropY)
    .resize(requiredWidth, requiredHeight)
    .toBuffer('PNG', function (err, buffer) {
    if (err) {
    reject(err);
    } else {
    resolve(buffer);
    }
    });

    });

    }.bind(this));
    };