Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
function diffPNGs(image1, image2, options) {
const {width, height} = image1;
if (width !== image2.width || height !== image2.height) {
throw new Error('Image sizes do not match');
}
const {threshold = 0.99, createDiffImage = false, tolerance = 0.1, includeAA = false} = options;
const diffImage = createDiffImage ? new Uint8Array(width * height) : null;
// pixelmatch returns the number of mismatched pixels
const mismatchedPixels = pixelmatch(
image1.data, // image 1
image2.data, // image 2
diffImage, // output
width, // width
height, // height
{threshold: tolerance, includeAA} // options
);
const match = 1 - mismatchedPixels / (width * height);
return {
match,
matchPercentage: `${(match * 100).toFixed(2)}%`,
success: match >= threshold,
diffImage
};
var width = refImageData.width;
var height = refImageData.height;
var canvasDiff = document.createElement('canvas');
var diffCtx = canvasDiff.getContext('2d');
canvasDiff.width = width;
canvasDiff.height = height;
var diff = diffCtx.createImageData(width, height);
var newImageData = diffCtx.createImageData(width, height);
resizeImageData(currentImageData, newImageData);
var expected = refImageData.data;
var actual = newImageData.data;
var threshold = typeof GFXTESTS_CONFIG.referenceCompareThreshold === 'undefined' ? 0.2 : GFXTESTS_CONFIG.referenceCompareThreshold;
var numDiffPixels = pixelmatch(expected, actual, diff.data, width, height, {threshold: threshold});
var diffPerc = numDiffPixels / (width * height) * 100;
var fail = diffPerc > 0.2; // diff perc 0 - 100%
var result = {result: 'pass'};
if (fail) {
var divError = document.getElementById('reference-images-error');
divError.querySelector('h3').innerHTML = `ERROR: Reference image mismatch (${diffPerc.toFixed(2)}% different pixels)`;
divError.style.display = 'block';
result = {
result: 'fail',
diffPerc: diffPerc,
numDiffPixels: numDiffPixels,
failReason: 'Reference image mismatch'
};
async function compareImages(a: string, b: string) {
// base64 strings are platform dependent and differs on win and *nix
// so we'll have to match them pixel by pixel
const [imageA, imageB] = await Promise.all([base64ToPNG(a), base64ToPNG(b)]);
if (imageA.width !== imageB.width || imageA.height !== imageB.height) return false;
return pixelmatch(imageA.data, imageB.data, null, imageA.width, imageA.height, {
threshold: 0,
}) === 0;
}
expectedJimp.getHeight(),
actualJimp.getHeight()
);
const differentSize =
expectedJimp.getWidth() !== actualJimp.getWidth() ||
expectedJimp.getHeight() !== actualJimp.getHeight();
if (differentSize) {
expectedJimp.crop(0, 0, smallestWidth, smallestHeight);
actualJimp.crop(0, 0, smallestWidth, smallestHeight);
}
const diffJimp = new Jimp(smallestWidth, smallestHeight, 0xffffffff);
const numDiffPixels = pixelmatch(
expectedJimp.bitmap.data,
actualJimp.bitmap.data,
diffJimp.bitmap.data, // this will be modified in place
smallestWidth,
smallestHeight,
{
diffColor: [this.diffColor.r, this.diffColor.g, this.diffColor.b],
threshold: this.threshold,
alpha: 0
}
);
const matches = numDiffPixels === 0;
if (differentSize) {
const wholeDiffJimp = new Jimp(biggestWidth, biggestHeight, '#ff0000');
const testDiff = (args, filepath) => {
const basename = path.basename(filepath);
execa.sync(cd('../bin/glsl2png.js'), args);
const actual = PNG.sync.read(fs.readFileSync(filepath));
const expected = PNG.sync.read(fs.readFileSync(cd(`fixtures/${basename}`)));
const numDiffPixels = pixelmatch(actual, expected, actual.width, actual.height, { threshold: 0.1 });
t.is(numDiffPixels, 0);
rimraf.sync(filepath);
};
compare(actual, expected, threshold = 0.1) {
if (actual.height !== expected.height || actual.width !== expected.width) {
return {
pass: false,
message: `Expected image dimensions (h x w) of ${expected.height}x${expected.width}.
Received an image with ${actual.height}x${actual.width}`,
};
}
const { width, height } = actual;
const differentPixels = pixelmatch(
getImageData(actual),
getImageData(expected),
null,
width,
height,
{ threshold },
);
return {
pass: differentPixels < 20,
message: `${differentPixels} pixels differ more than ${threshold *
100} percent between input and output.`,
};
},
};
const baseline = PNG.sync.read(baselineImage);
const test = PNG.sync.read(srcImage);
const isSameDimensions = baseline.width === test.width && baseline.height === test.height;
if (!isSameDimensions) {
return of({
isSameDimensions
});
}
const diffImageKey = `${testSessionId}.diff.png`;
const diff = new PNG({
width: baseline.width,
height: baseline.height
});
const pixelMisMatchCount = Pixelmatch(baseline.data, test.data, diff.data, baseline.width, baseline.height, {
threshold: environment.diffOptions.threshold,
includeAA: environment.diffOptions.includeAA
});
const subject: Subject = new Subject();
diff.pack();
const chunks = [];
diff.on('data', function(chunk) {
chunks.push(chunk);
});
diff.on('end', function() {
subject.next(Buffer.concat(chunks));
subject.complete();
});
return subject.asObservable().pipe(
`The screenshot:[${fileName}] taken during the test has a ` +
`width:[${screenShotFromTest.width}] that differs from the ` +
`expected: [${screenShotFromTruth.width}].`
);
}
if (screenShotFromTest.height !== screenShotFromTruth.height) {
throw new Error(
`The screenshot:[${fileName}] taken during the test has a ` +
`height:[${screenShotFromTest.height}] that differs from the ` +
`expected: [${screenShotFromTruth.height}].`
);
}
const diff = new PNG({ width: screenShotFromTest.width, height: screenShotFromTruth.height });
const numDiffPixels = pixelmatch(
screenShotFromTest.data,
screenShotFromTruth.data,
diff.data,
screenShotFromTest.width,
screenShotFromTest.height,
{ threshold: 0.1 }
);
if (numDiffPixels !== 0) {
const localMessage =
`\nCompare the output from expected:[${constants.screenShotsTruthDir}] ` +
`with outcome:[${constants.screenShotsOutputDir}]`;
const circleCIMessage = '\nCheck the Artifacts tab in the CircleCi build output for the actual screenshots.';
const checkMessage = process.env.CIRCLE_SHA1 ? circleCIMessage : localMessage;
let msg =
`\nThe screenshot:[${constants.screenShotsOutputDir}/${fileName}.png] ` +
let baselinePNG = PNG.sync.read(baselinePNGFile.buffer);
let changesPNG = PNG.sync.read(changesPNGFile.buffer);
let { width, height } = baselinePNG;
let diffPNG = new PNG({ width, height });
if (baselinePNGFile.buffer.equals(changesPNGFile.buffer)) {
if (diffPNGFile) {
await diffPNGFile.delete();
}
return;
}
let error = new TractorError(`Visual Regression failed for ${filePath}`);
if (imagesAreSameSize(baselinePNG, changesPNG)) {
const diffPixelCount = pixelmatch(baselinePNG.data, changesPNG.data, diffPNG.data, width, height, { threshold: 0.1 });
if (diffPixelCount === 0) {
return;
}
} else {
error = new TractorError(`New screenshot for ${filePath} is not the same size as baseline.`);
}
diffPNGFile = diffPNGFile || new DiffPNGFile(diffsPath, fileStructure);
await diffPNGFile.save(PNG.sync.write(diffPNG));
throw error;
}