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+
import resizeImageWidth from '../resizeImageWidth';
3+
4+
const testImageBeforePath = './src/algorithms/image-processing/seam-carving/__tests__/test-image-before.jpg';
5+
const testImageAfterPath = './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+
return Promise.all([
11+
loadImage(testImageBeforePath),
12+
loadImage(testImageAfterPath),
13+
]).then(([imgBefore, imgAfter]) => {
14+
// Original image.
15+
const canvasBefore = createCanvas(imgBefore.width, imgBefore.height);
16+
const ctxBefore = canvasBefore.getContext('2d');
17+
ctxBefore.drawImage(imgBefore, 0, 0, imgBefore.width, imgBefore.height);
18+
const imgDataBefore = ctxBefore.getImageData(0, 0, imgBefore.width, imgBefore.height);
19+
20+
// Resized image saved.
21+
const canvasAfter = createCanvas(imgAfter.width, imgAfter.height);
22+
const ctxAfter = canvasAfter.getContext('2d');
23+
ctxAfter.drawImage(imgAfter, 0, 0, imgAfter.width, imgAfter.height);
24+
25+
const toWidth = 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+
const canvasTest = createCanvas(resizedSize.w, resizedSize.h);
37+
const ctxTest = canvasTest.getContext('2d');
38+
ctxTest.putImageData(resizedImg, 0, 0, 0, 0, resizedSize.w, resizedSize.h);
39+
const imgDataTest = 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+
});

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy