Skip to content
This repository has been archived by the owner on May 1, 2020. It is now read-only.

Commit

Permalink
Merge pull request #7 from yahoo/image_cropping
Browse files Browse the repository at this point in the history
Add image cropping
  • Loading branch information
marcelerz committed Nov 28, 2014
2 parents 46f449f + c224211 commit 54212fb
Show file tree
Hide file tree
Showing 4 changed files with 389 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ Changelog

v1.0.3
* Image loading from Buffer
* Input image cropping

v1.0.2 - (11/09/14)
* Add shift feature for issues with anti-aliasing
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ A lightweight image comparison tool
* [Usage](#usage)
* [Command-Line Usage](#command-line-usage)
* [Object Usage](#object-usage)
* [Cropping](#cropping)
* [Logging](#logging)
* [Examples](#examples)
* [Results](#results)
Expand Down Expand Up @@ -143,6 +144,8 @@ All the parameters that were available in the command-line tool are also availab
* ```hShift``` Horizontal shift for possible antialiasing (default: 2) Set to 0 to turn this off.
* ```vShift``` Vertical shift for possible antialiasing (default: 2) Set to 0 to turn this off.
* ```hideShift``` Uses the background color for "highlighting" shifts. (default: false)
* ```cropImageA``` Cropping for first image (default: no cropping) - Format: { x:<int>, y:<int>, width:<int>, height:<int> }
* ```cropImageB``` Cropping for second image (default: no cropping) - Format: { x:<int>, y:<int>, width:<int>, height:<int> }
**Example:**
```javascript
Expand Down Expand Up @@ -172,6 +175,9 @@ var firstImage = PNGImage.readImage('path/to/first/image', function (err) {
});
```
####Cropping
Images can be cropped before they are compared by using the ```cropImageA``` or ```cropImageB``` parameters. Single values can be left off, and the system will calculate the correct dimensions. However, ```x```/```y``` coordinates have priority over ```width```/```height``` as the position are usually more important than the dimensions - image will also be clipped by the system when needed.
####Logging
By default, the logger doesn't log events anywhere, but you can change this behavior by overwriting ```blinkDiff.log```:
Expand Down Expand Up @@ -246,6 +252,7 @@ Also, even if you simply gave us an idea for a feature and did not actually writ
* Documentation
* [koola](https://github.com/koola)
* Image loading from Buffer
* Input image cropping
##Third-party libraries
Expand Down
90 changes: 90 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ var assert = require('assert'),
* @param {boolean} [options.hideShift=false] Hides shift highlighting by using the background color instead
* @param {int} [options.hShift=2] Horizontal shift for possible antialiasing
* @param {int} [options.vShift=2] Vertical shift for possible antialiasing
* @param {object} [options.cropImageA=null] Cropping for first image (default: no cropping)
* @param {int} [options.cropImageA.x=0] Coordinate for left corner of cropping region
* @param {int} [options.cropImageA.y=0] Coordinate for top corner of cropping region
* @param {int} [options.cropImageA.width] Width of cropping region (default: Width that is left)
* @param {int} [options.cropImageA.height] Height of cropping region (default: Height that is left)
* @param {object} [options.cropImageB=null] Cropping for second image (default: no cropping)
* @param {int} [options.cropImageB.x=0] Coordinate for left corner of cropping region
* @param {int} [options.cropImageB.y=0] Coordinate for top corner of cropping region
* @param {int} [options.cropImageB.width] Width of cropping region (default: Width that is left)
* @param {int} [options.cropImageB.height] Height of cropping region (default: Height that is left)
*
* @property {PNGImage} _imageA
* @property {PNGImage} _imageACompare
Expand Down Expand Up @@ -80,6 +90,16 @@ var assert = require('assert'),
* @property {boolean} _composeTopToBottom
* @property {int} _hShift
* @property {int} _vShift
* @property {object} _cropImageA
* @property {int} _cropImageA.x
* @property {int} _cropImageA.y
* @property {int} _cropImageA.width
* @property {int} _cropImageA.height
* @property {object} _cropImageB
* @property {int} _cropImageB.x
* @property {int} _cropImageB.y
* @property {int} _cropImageB.width
* @property {int} _cropImageB.height
*/
function BlinkDiff (options) {

Expand Down Expand Up @@ -142,6 +162,9 @@ function BlinkDiff (options) {

this._hShift = options.hShift || 2;
this._vShift = options.vShift || 2;

this._cropImageA = options.cropImageA;
this._cropImageB = options.cropImageB;
}


Expand Down Expand Up @@ -264,6 +287,16 @@ BlinkDiff.prototype = {
}.bind(this)).then(function (imageB) {
this._imageB = imageB;

// Crop images if requested
if (this._cropImageA) {
this._cropDimensions(this._imageA.getWidth(), this._imageA.getHeight(), this._cropImageA);
this._crop("Image-A", this._imageA, this._cropImageA);
}
if (this._cropImageB) {
this._cropDimensions(this._imageB.getWidth(), this._imageB.getHeight(), this._cropImageB);
this._crop("Image-B", this._imageB, this._cropImageB);
}

// Always clip
this._clip(this._imageA, this._imageB);

Expand Down Expand Up @@ -479,6 +512,63 @@ BlinkDiff.prototype = {
}
},

/**
* Crops the source image to the bounds of rect
*
* @method _crop
* @param {string} which Title of image to crop
* @param {PNGImage} image Source image
* @param {object} rect Values for rect
* @param {int} rect.x X value of rect
* @param {int} rect.y Y value of rect
* @param {int} rect.width Width value of rect
* @param {int} rect.height Height value of rect
* @private
*/
_crop: function (which, image, rect) {

this.log("Cropping " + which + " from " + rect.x + "," + rect.y + " by " + rect.width + " x " + rect.height);

image.clip(rect.x, rect.y, rect.width, rect.height);
},

/**
* Correcting cropping dimensions if necessary
*
* Note:
* Priority is on the x/y coordinates, and not on the dimensions since the dimensions will then be clipped anyways.
*
* @method _cropDimensions
* @param {int} width
* @param {int} height
* @param {object} rect Values for rect
* @param {int} rect.x X value of rect
* @param {int} rect.y Y value of rect
* @param {int} rect.width Width value of rect
* @param {int} rect.height Height value of rect
* @private
*/
_cropDimensions: function (width, height, rect) {

// Add values if not given
rect.x = rect.x || 0;
rect.y = rect.y || 0;
rect.width = rect.width || width;
rect.height = rect.height || height;

// Check negative values
rect.x = Math.max(0, rect.x);
rect.y = Math.max(0, rect.y);
rect.width = Math.max(0, rect.width);
rect.height = Math.max(0, rect.height);

// Check dimensions
rect.x = Math.min(rect.x, width - 1); // -1 to make sure that there is an image
rect.y = Math.min(rect.y, height - 1);
rect.width = Math.min(rect.width, width - rect.x);
rect.height = Math.min(rect.height, height - rect.y);
},


/**
* Calculates the distance of colors in the 4 dimensional color space
Expand Down
Loading

0 comments on commit 54212fb

Please sign in to comment.