mirror of
https://github.moeyy.xyz/https://github.com/trekhleb/javascript-algorithms.git
synced 2024-12-26 23:21:18 +08:00
Test that two images are identical for the Seam Carving algorithm. (#694)
* Test that two images are identical for the Seam Carving algorithm. * Tune the Seam Carving tests. * Tune the Seam Carving tests. * Tune the Seam Carving tests. * Tune the Seam Carving tests.
This commit is contained in:
parent
f0b246a521
commit
cfd9a630ff
@ -1,5 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
. "$(dirname "$0")/_/husky.sh"
|
. "$(dirname "$0")/_/husky.sh"
|
||||||
|
|
||||||
|
# @TODO: Implement the pre-commit checks.
|
||||||
# npm run lint
|
# npm run lint
|
||||||
# npm run test
|
# npm run test
|
||||||
|
@ -4,6 +4,40 @@ import resizeImageWidth from '../resizeImageWidth';
|
|||||||
const testImageBeforePath = './src/algorithms/image-processing/seam-carving/__tests__/test-image-before.jpg';
|
const testImageBeforePath = './src/algorithms/image-processing/seam-carving/__tests__/test-image-before.jpg';
|
||||||
const testImageAfterPath = './src/algorithms/image-processing/seam-carving/__tests__/test-image-after.jpg';
|
const testImageAfterPath = './src/algorithms/image-processing/seam-carving/__tests__/test-image-after.jpg';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two images and finds the number of different pixels.
|
||||||
|
*
|
||||||
|
* @param {ImageData} imgA - ImageData for the first image.
|
||||||
|
* @param {ImageData} imgB - ImageData for the second image.
|
||||||
|
* @param {number} threshold - Color difference threshold [0..255]. Smaller - stricter.
|
||||||
|
* @returns {number} - Number of different pixels.
|
||||||
|
*/
|
||||||
|
function pixelsDiff(imgA, imgB, threshold = 0) {
|
||||||
|
if (imgA.width !== imgB.width || imgA.height !== imgB.height) {
|
||||||
|
throw new Error('Images must have the same size');
|
||||||
|
}
|
||||||
|
|
||||||
|
let differentPixels = 0;
|
||||||
|
const numColorParams = 4; // RGBA
|
||||||
|
|
||||||
|
for (let pixelIndex = 0; pixelIndex < imgA.data.length; pixelIndex += numColorParams) {
|
||||||
|
// Get pixel's color for each image.
|
||||||
|
const [aR, aG, aB] = imgA.data.subarray(pixelIndex, pixelIndex + numColorParams);
|
||||||
|
const [bR, bG, bB] = imgB.data.subarray(pixelIndex, pixelIndex + numColorParams);
|
||||||
|
|
||||||
|
// Get average pixel's color for each image (make them greyscale).
|
||||||
|
const aAvgColor = Math.floor((aR + aG + aB) / 3);
|
||||||
|
const bAvgColor = Math.floor((bR + bG + bB) / 3);
|
||||||
|
|
||||||
|
// Compare pixel colors.
|
||||||
|
if (Math.abs(aAvgColor - bAvgColor) > threshold) {
|
||||||
|
differentPixels += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return differentPixels;
|
||||||
|
}
|
||||||
|
|
||||||
describe('resizeImageWidth', () => {
|
describe('resizeImageWidth', () => {
|
||||||
it('should perform content-aware image width reduction', () => {
|
it('should perform content-aware image width reduction', () => {
|
||||||
// @see: https://jestjs.io/docs/asynchronous
|
// @see: https://jestjs.io/docs/asynchronous
|
||||||
@ -21,6 +55,7 @@ describe('resizeImageWidth', () => {
|
|||||||
const canvasAfter = createCanvas(imgAfter.width, imgAfter.height);
|
const canvasAfter = createCanvas(imgAfter.width, imgAfter.height);
|
||||||
const ctxAfter = canvasAfter.getContext('2d');
|
const ctxAfter = canvasAfter.getContext('2d');
|
||||||
ctxAfter.drawImage(imgAfter, 0, 0, imgAfter.width, imgAfter.height);
|
ctxAfter.drawImage(imgAfter, 0, 0, imgAfter.width, imgAfter.height);
|
||||||
|
const imgDataAfter = ctxAfter.getImageData(0, 0, imgAfter.width, imgAfter.height);
|
||||||
|
|
||||||
const toWidth = Math.floor(imgBefore.width / 2);
|
const toWidth = Math.floor(imgBefore.width / 2);
|
||||||
|
|
||||||
@ -44,8 +79,13 @@ describe('resizeImageWidth', () => {
|
|||||||
expect(imgDataTest.width).toBe(imgAfter.width);
|
expect(imgDataTest.width).toBe(imgAfter.width);
|
||||||
expect(imgDataTest.height).toBe(imgAfter.height);
|
expect(imgDataTest.height).toBe(imgAfter.height);
|
||||||
|
|
||||||
// @TODO: Check that images are identical.
|
const colorThreshold = 50;
|
||||||
// expect(canvasTest.toDataURL()).toEqual(canvasAfter.toDataURL());
|
const differentPixels = pixelsDiff(imgDataTest, imgDataAfter, colorThreshold);
|
||||||
|
|
||||||
|
// Allow 10% of pixels to be different
|
||||||
|
const pixelsThreshold = Math.floor((imgAfter.width * imgAfter.height) / 10);
|
||||||
|
|
||||||
|
expect(differentPixels).toBeLessThanOrEqual(pixelsThreshold);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user