Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit cfd9a63

Browse files
Test that two images are identical for the Seam Carving algorithm. (trekhleb#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.
1 parent f0b246a commit cfd9a63

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

‎.husky/pre-commit‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/bin/sh
22
. "$(dirname "0ドル")/_/husky.sh"
33

4+
# @TODO: Implement the pre-commit checks.
45
# npm run lint
56
# npm run test

‎src/algorithms/image-processing/seam-carving/__tests__/resizeImageWidth.test.js‎

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,40 @@ import resizeImageWidth from '../resizeImageWidth';
44
const testImageBeforePath = './src/algorithms/image-processing/seam-carving/__tests__/test-image-before.jpg';
55
const testImageAfterPath = './src/algorithms/image-processing/seam-carving/__tests__/test-image-after.jpg';
66

7+
/**
8+
* Compares two images and finds the number of different pixels.
9+
*
10+
* @param {ImageData} imgA - ImageData for the first image.
11+
* @param {ImageData} imgB - ImageData for the second image.
12+
* @param {number} threshold - Color difference threshold [0..255]. Smaller - stricter.
13+
* @returns {number} - Number of different pixels.
14+
*/
15+
function pixelsDiff(imgA, imgB, threshold = 0) {
16+
if (imgA.width !== imgB.width || imgA.height !== imgB.height) {
17+
throw new Error('Images must have the same size');
18+
}
19+
20+
let differentPixels = 0;
21+
const numColorParams = 4; // RGBA
22+
23+
for (let pixelIndex = 0; pixelIndex < imgA.data.length; pixelIndex += numColorParams) {
24+
// Get pixel's color for each image.
25+
const [aR, aG, aB] = imgA.data.subarray(pixelIndex, pixelIndex + numColorParams);
26+
const [bR, bG, bB] = imgB.data.subarray(pixelIndex, pixelIndex + numColorParams);
27+
28+
// Get average pixel's color for each image (make them greyscale).
29+
const aAvgColor = Math.floor((aR + aG + aB) / 3);
30+
const bAvgColor = Math.floor((bR + bG + bB) / 3);
31+
32+
// Compare pixel colors.
33+
if (Math.abs(aAvgColor - bAvgColor) > threshold) {
34+
differentPixels += 1;
35+
}
36+
}
37+
38+
return differentPixels;
39+
}
40+
741
describe('resizeImageWidth', () => {
842
it('should perform content-aware image width reduction', () => {
943
// @see: https://jestjs.io/docs/asynchronous
@@ -21,6 +55,7 @@ describe('resizeImageWidth', () => {
2155
const canvasAfter = createCanvas(imgAfter.width, imgAfter.height);
2256
const ctxAfter = canvasAfter.getContext('2d');
2357
ctxAfter.drawImage(imgAfter, 0, 0, imgAfter.width, imgAfter.height);
58+
const imgDataAfter = ctxAfter.getImageData(0, 0, imgAfter.width, imgAfter.height);
2459

2560
const toWidth = Math.floor(imgBefore.width / 2);
2661

@@ -44,8 +79,13 @@ describe('resizeImageWidth', () => {
4479
expect(imgDataTest.width).toBe(imgAfter.width);
4580
expect(imgDataTest.height).toBe(imgAfter.height);
4681

47-
// @TODO: Check that images are identical.
48-
// expect(canvasTest.toDataURL()).toEqual(canvasAfter.toDataURL());
82+
const colorThreshold = 50;
83+
const differentPixels = pixelsDiff(imgDataTest, imgDataAfter, colorThreshold);
84+
85+
// Allow 10% of pixels to be different
86+
const pixelsThreshold = Math.floor((imgAfter.width * imgAfter.height) / 10);
87+
88+
expect(differentPixels).toBeLessThanOrEqual(pixelsThreshold);
4989
});
5090
});
5191
});

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /