mirror of
https://github.moeyy.xyz/https://github.com/trekhleb/javascript-algorithms.git
synced 2024-12-25 22:46:20 +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
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
# @TODO: Implement the pre-commit checks.
|
||||
# npm run lint
|
||||
# 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 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', () => {
|
||||
it('should perform content-aware image width reduction', () => {
|
||||
// @see: https://jestjs.io/docs/asynchronous
|
||||
@ -21,6 +55,7 @@ describe('resizeImageWidth', () => {
|
||||
const canvasAfter = createCanvas(imgAfter.width, imgAfter.height);
|
||||
const ctxAfter = canvasAfter.getContext('2d');
|
||||
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);
|
||||
|
||||
@ -44,8 +79,13 @@ describe('resizeImageWidth', () => {
|
||||
expect(imgDataTest.width).toBe(imgAfter.width);
|
||||
expect(imgDataTest.height).toBe(imgAfter.height);
|
||||
|
||||
// @TODO: Check that images are identical.
|
||||
// expect(canvasTest.toDataURL()).toEqual(canvasAfter.toDataURL());
|
||||
const colorThreshold = 50;
|
||||
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