Skip to content

Commit f0b246a

Browse files
authored
Adding a Seam Carving algorithm with Dynamic Programming implementation. (trekhleb#693)
* Adding a Seam Carving algorithm with Dynamic Programming implementation. * Adding a Seam Carving algorithm with Dynamic Programming implementation. * Adding a Seam Carving algorithm with Dynamic Programming implementation. * Testing Husky integration. * Testing Husky integration.
1 parent 028ffa6 commit f0b246a

File tree

13 files changed

+2838
-1193
lines changed

13 files changed

+2838
-1193
lines changed

‎.husky/.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
_

‎.husky/pre-commit‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/sh
2+
."$(dirname "$0")/_/husky.sh"
3+
4+
# npm run lint
5+
# npm run test

‎.huskyrc.json‎

Lines changed: 0 additions & 5 deletions
This file was deleted.

‎README.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ a set of rules that precisely define a sequence of operations.
152152
*`B`[NanoNeuron](https://github.com/trekhleb/nano-neuron) - 7 simple JS functions that illustrate how machines can actually learn (forward/backward propagation)
153153
*`B`[k-NN](src/algorithms/ml/knn) - k-nearest neighbors classification algorithm
154154
*`B`[k-Means](src/algorithms/ml/k-means) - k-Means clustering algorithm
155+
***Image Processing**
156+
*`B`[Seam Carving](src/algorithms/image-processing/seam-carving) - content-aware image resizing algorithm
155157
***Uncategorized**
156158
*`B`[Tower of Hanoi](src/algorithms/uncategorized/hanoi-tower)
157159
*`B`[Square Matrix Rotation](src/algorithms/uncategorized/square-matrix-rotation) - in-place algorithm
@@ -203,6 +205,7 @@ algorithm is an abstraction higher than a computer program.
203205
*`B`[Unique Paths](src/algorithms/uncategorized/unique-paths)
204206
*`B`[Rain Terraces](src/algorithms/uncategorized/rain-terraces) - trapping rain water problem
205207
*`B`[Recursive Staircase](src/algorithms/uncategorized/recursive-staircase) - count the number of ways to reach to the top
208+
*`B`[Seam Carving](src/algorithms/image-processing/seam-carving) - content-aware image resizing algorithm
206209
*`A`[Levenshtein Distance](src/algorithms/string/levenshtein-distance) - minimum edit distance between two sequences
207210
*`A`[Longest Common Subsequence](src/algorithms/sets/longest-common-subsequence) (LCS)
208211
*`A`[Longest Common Substring](src/algorithms/string/longest-common-substring)

‎package-lock.json‎

Lines changed: 1464 additions & 1186 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"lint": "eslint ./src/**",
88
"test": "jest",
99
"coverage": "npm run test -- --coverage",
10-
"ci": "npm run lint && npm run coverage"
10+
"ci": "npm run lint && npm run coverage",
11+
"prepare": "husky install"
1112
},
1213
"repository":{
1314
"type": "git",
@@ -37,13 +38,14 @@
3738
"@babel/cli": "7.12.10",
3839
"@babel/preset-env": "7.12.11",
3940
"@types/jest": "26.0.19",
41+
"canvas": "^2.7.0",
4042
"eslint": "7.16.0",
4143
"eslint-config-airbnb": "18.2.1",
4244
"eslint-plugin-import": "2.22.1",
4345
"eslint-plugin-jest": "24.1.3",
4446
"eslint-plugin-jsx-a11y": "6.4.1",
4547
"eslint-plugin-react": "7.21.5",
46-
"husky": "4.3.6",
48+
"husky": "6.0.0",
4749
"jest": "26.6.3"
4850
},
4951
"dependencies":{}

‎src/algorithms/image-processing/seam-carving/README.md‎

Lines changed: 509 additions & 0 deletions
Large diffs are not rendered by default.

‎src/algorithms/image-processing/seam-carving/README.ru-RU.md‎

Lines changed: 509 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import{createCanvas,loadImage}from'canvas';
2+
importresizeImageWidthfrom'../resizeImageWidth';
3+
4+
consttestImageBeforePath='./src/algorithms/image-processing/seam-carving/__tests__/test-image-before.jpg';
5+
consttestImageAfterPath='./src/algorithms/image-processing/seam-carving/__tests__/test-image-after.jpg';
6+
7+
describe('resizeImageWidth',()=>{
8+
it('should perform content-aware image width reduction',()=>{
9+
// @see: https://jestjs.io/docs/asynchronous
10+
returnPromise.all([
11+
loadImage(testImageBeforePath),
12+
loadImage(testImageAfterPath),
13+
]).then(([imgBefore,imgAfter])=>{
14+
// Original image.
15+
constcanvasBefore=createCanvas(imgBefore.width,imgBefore.height);
16+
constctxBefore=canvasBefore.getContext('2d');
17+
ctxBefore.drawImage(imgBefore,0,0,imgBefore.width,imgBefore.height);
18+
constimgDataBefore=ctxBefore.getImageData(0,0,imgBefore.width,imgBefore.height);
19+
20+
// Resized image saved.
21+
constcanvasAfter=createCanvas(imgAfter.width,imgAfter.height);
22+
constctxAfter=canvasAfter.getContext('2d');
23+
ctxAfter.drawImage(imgAfter,0,0,imgAfter.width,imgAfter.height);
24+
25+
consttoWidth=Math.floor(imgBefore.width/2);
26+
27+
const{
28+
img: resizedImg,
29+
size: resizedSize,
30+
}=resizeImageWidth({img: imgDataBefore, toWidth });
31+
32+
expect(resizedImg).toBeDefined();
33+
expect(resizedSize).toBeDefined();
34+
35+
// Resized image generated.
36+
constcanvasTest=createCanvas(resizedSize.w,resizedSize.h);
37+
constctxTest=canvasTest.getContext('2d');
38+
ctxTest.putImageData(resizedImg,0,0,0,0,resizedSize.w,resizedSize.h);
39+
constimgDataTest=ctxTest.getImageData(0,0,resizedSize.w,resizedSize.h);
40+
41+
expect(resizedSize).toEqual({w: toWidth,h: imgBefore.height});
42+
expect(imgDataTest.width).toBe(toWidth);
43+
expect(imgDataTest.height).toBe(imgBefore.height);
44+
expect(imgDataTest.width).toBe(imgAfter.width);
45+
expect(imgDataTest.height).toBe(imgAfter.height);
46+
47+
// @TODO: Check that images are identical.
48+
// expect(canvasTest.toDataURL()).toEqual(canvasAfter.toDataURL());
49+
});
50+
});
51+
});
5.95 KB
Loading

0 commit comments

Comments
(0)