Skip to content

Commit

Permalink
Fixes HumbleSoftware#34 (Diff swallows black color in added areas): a…
Browse files Browse the repository at this point in the history
…dds options.ligthness, options.rgb and options.stack to customize the diff image.
  • Loading branch information
B2F committed Apr 22, 2015
1 parent e92cccf commit 6dc63b3
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 16 deletions.
57 changes: 49 additions & 8 deletions imagediff.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,12 @@
i, j, k, v;

for (i = 0; i < length; i += 4) {
cData[i] = Math.abs(aData[i] - bData[i]);
cData[i+1] = Math.abs(aData[i+1] - bData[i+1]);
cData[i+2] = Math.abs(aData[i+2] - bData[i+2]);
cData[i+3] = Math.abs(255 - Math.abs(aData[i+3] - bData[i+3]));
var pixelA = Array.prototype.slice.call(aData, i, i+3);
var pixelB = Array.prototype.slice.call(bData, i, i+3);
var diffPixel = diffPixels(pixelA, pixelB, options);
for (var rgbIndex = 0; rgbIndex < 4; rgbIndex++) {
cData[i+rgbIndex] = diffPixel[rgbIndex];
}
}

return c;
Expand Down Expand Up @@ -231,7 +233,6 @@
cData[i+0] = aData[j+0]; // r
cData[i+1] = aData[j+1]; // g
cData[i+2] = aData[j+2]; // b
// cData[i+3] = aData[j+3]; // a
}
}

Expand All @@ -241,9 +242,12 @@
for (column = b.width; column--;) {
i = 4 * ((row + rowOffset) * width + (column + columnOffset));
j = 4 * (row * b.width + column);
cData[i+0] = Math.abs(cData[i+0] - bData[j+0]); // r
cData[i+1] = Math.abs(cData[i+1] - bData[j+1]); // g
cData[i+2] = Math.abs(cData[i+2] - bData[j+2]); // b
var pixelA = Array.prototype.slice.call(cData, i, i+3);
var pixelB = Array.prototype.slice.call(bData, j, j+3);
var diffPixel = diffPixels(pixelA, pixelB, options);
for (var rgbIndex = 0; rgbIndex < 4; rgbIndex++) {
cData[i+rgbIndex] = diffPixel[rgbIndex];
}
}
}

Expand All @@ -261,6 +265,43 @@
return c;
}

/**
* Differentiates two rgb pixels by subtracting color values.
* The light value for each color marks the difference gap.
*
* @see https://github.com/HumbleSoftware/js-imagediff/issues/34
* @param {Object} options
* options.lightness: light added to color value, increasing differences visibility
* options.rgb : array used to specify rgb balance instead of lightness
* options.stack: stack differences on top of the original image, preserving common pixels
*
* @returns {Number} a color value between 0 and 255.
*/
function diffPixels(pixelA, pixelB, options) {
var lightness = options.lightness || 25;
// A custom RGB balance can be applied to color variations.
var diffColor = options.rgb || [lightness,lightness,lightness];
// Set stack to true if you want to display common pixels instead of a black background:
var stack = options.stack || false;
// diffPixel = [r,g,b,a]
var diffPixel = [0,0,0,255];
for (var rgbIndex = 0; rgbIndex < 3 ; rgbIndex++) {
diffPixel[rgbIndex] = Math.abs(pixelA[rgbIndex] - pixelB[rgbIndex]);
// Optionally colorize area of difference, adds visibility with lightness.
if (diffPixel[rgbIndex] > 0) {
// Lightens color differences for increased visibilty.
diffPixel[rgbIndex] += diffColor[rgbIndex];
// Math.min is a failsafe mean for higher diffColor than 255.
diffPixel[rgbIndex] = Math.min(diffPixel[rgbIndex], 255);
}
else if (stack) {
// If options.stack and no pixel differences are found,
// print original pixel instead of a black (0) pixel.
diffPixel[rgbIndex] = pixelA[rgbIndex];
}
}
return diffPixel;
}

// Validation
function checkType () {
Expand Down
57 changes: 49 additions & 8 deletions js/imagediff.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,12 @@
i, j, k, v;

for (i = 0; i < length; i += 4) {
cData[i] = Math.abs(aData[i] - bData[i]);
cData[i+1] = Math.abs(aData[i+1] - bData[i+1]);
cData[i+2] = Math.abs(aData[i+2] - bData[i+2]);
cData[i+3] = Math.abs(255 - Math.abs(aData[i+3] - bData[i+3]));
var pixelA = Array.prototype.slice.call(aData, i, i+3);
var pixelB = Array.prototype.slice.call(bData, i, i+3);
var diffPixel = diffPixels(pixelA, pixelB, options);
for (var rgbIndex = 0; rgbIndex < 4; rgbIndex++) {
cData[i+rgbIndex] = diffPixel[rgbIndex];
}
}

return c;
Expand Down Expand Up @@ -224,7 +226,6 @@
cData[i+0] = aData[j+0]; // r
cData[i+1] = aData[j+1]; // g
cData[i+2] = aData[j+2]; // b
// cData[i+3] = aData[j+3]; // a
}
}

Expand All @@ -234,9 +235,12 @@
for (column = b.width; column--;) {
i = 4 * ((row + rowOffset) * width + (column + columnOffset));
j = 4 * (row * b.width + column);
cData[i+0] = Math.abs(cData[i+0] - bData[j+0]); // r
cData[i+1] = Math.abs(cData[i+1] - bData[j+1]); // g
cData[i+2] = Math.abs(cData[i+2] - bData[j+2]); // b
var pixelA = Array.prototype.slice.call(cData, i, i+3);
var pixelB = Array.prototype.slice.call(bData, j, j+3);
var diffPixel = diffPixels(pixelA, pixelB, options);
for (var rgbIndex = 0; rgbIndex < 4; rgbIndex++) {
cData[i+rgbIndex] = diffPixel[rgbIndex];
}
}
}

Expand All @@ -254,6 +258,43 @@
return c;
}

/**
* Differentiates two rgb pixels by subtracting color values.
* The light value for each color marks the difference gap.
*
* @see https://github.com/HumbleSoftware/js-imagediff/issues/34
* @param {Object} options
* options.lightness: light added to color value, increasing differences visibility
* options.rgb : array used to specify rgb balance instead of lightness
* options.stack: stack differences on top of the original image, preserving common pixels
*
* @returns {Number} a color value between 0 and 255.
*/
function diffPixels(pixelA, pixelB, options) {
var lightness = options.lightness || 25;
// A custom RGB balance can be applied to color variations.
var diffColor = options.rgb || [lightness,lightness,lightness];
// Set stack to true if you want to display common pixels instead of a black background:
var stack = options.stack || false;
// diffPixel = [r,g,b,a]
var diffPixel = [0,0,0,255];
for (var rgbIndex = 0; rgbIndex < 3 ; rgbIndex++) {
diffPixel[rgbIndex] = Math.abs(pixelA[rgbIndex] - pixelB[rgbIndex]);
// Optionally colorize area of difference, adds visibility with lightness.
if (diffPixel[rgbIndex] > 0) {
// Lightens color differences for increased visibilty.
diffPixel[rgbIndex] += diffColor[rgbIndex];
// Math.min is a failsafe mean for higher diffColor than 255.
diffPixel[rgbIndex] = Math.min(diffPixel[rgbIndex], 255);
}
else if (stack) {
// If options.stack and no pixel differences are found,
// print original pixel instead of a black (0) pixel.
diffPixel[rgbIndex] = pixelA[rgbIndex];
}
}
return diffPixel;
}

// Validation
function checkType () {
Expand Down

0 comments on commit 6dc63b3

Please sign in to comment.