Skip to content
This repository was archived by the owner on Jul 26, 2025. It is now read-only.

Commit ae0aeed

Browse files
committed
feat: implement enhanceContrast
1 parent c7b9089 commit ae0aeed

File tree

4 files changed

+104
-0
lines changed

4 files changed

+104
-0
lines changed
63.8 KB
Loading
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { enhanceContrast } from '../enhanceContrast';
2+
3+
test('3x1 rgba image, custom output min and max', () => {
4+
const image = testUtils.createRgbaImage([
5+
[0, 100, 0, 50],
6+
[127, 150, 0, 50],
7+
[255, 200, 0, 50],
8+
]);
9+
10+
const result = enhanceContrast(image);
11+
12+
expect(result).toMatchImageData([
13+
[0, 0, 0, 50],
14+
[127, 127, 0, 50],
15+
[255, 255, 0, 50],
16+
]);
17+
});
18+
19+
test('1x3 grey image', () => {
20+
const image = testUtils.createGreyImage([[50, 100]]);
21+
expect(enhanceContrast(image)).toMatchImageData([[0, 255]]);
22+
});
23+
24+
test('alpha should not be modified', () => {
25+
const image = testUtils.createGreyaImage([
26+
[50, 100],
27+
[100, 50],
28+
]);
29+
expect(enhanceContrast(image)).toMatchImageData([
30+
[0, 100],
31+
[255, 50],
32+
]);
33+
});
34+
35+
test('out option', () => {
36+
const image = testUtils.createGreyaImage([
37+
[0, 10],
38+
[30, 40],
39+
[60, 70],
40+
]);
41+
const result = enhanceContrast(image, { out: image });
42+
expect(result).toMatchImageData([
43+
[0, 10],
44+
[127, 40],
45+
[255, 70],
46+
]);
47+
expect(result).toBe(image);
48+
});
49+
50+
test('bigger image', () => {
51+
const image = testUtils.load('featureMatching/id-crops/crop1.png');
52+
expect(enhanceContrast(image)).toMatchImageSnapshot();
53+
});

src/filters/enhanceContrast.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { Image } from '../Image';
2+
import checkProcessable from '../utils/checkProcessable';
3+
import { ImageColorModel } from '../utils/constants/colorModels';
4+
import { getOutputImage } from '../utils/getOutputImage';
5+
6+
export interface EnhanceContrastOptions {
7+
/**
8+
* Image to which to output.
9+
*/
10+
out?: Image;
11+
}
12+
13+
/**
14+
* Enhance the contrast of an image by spanning each channel on the range [0, image.maxValue].
15+
*
16+
* @param image - The image to enhance.
17+
* @param options - Enhance contrast options.
18+
* @returns The enhanced image.
19+
*/
20+
export function enhanceContrast(
21+
image: Image,
22+
options: EnhanceContrastOptions = {},
23+
): Image {
24+
checkProcessable(image, {
25+
bitDepth: [8, 16],
26+
});
27+
28+
let newImage = getOutputImage(image, options, { clone: true });
29+
30+
const minMax = image.minMax();
31+
32+
let channels: number[] = new Array(image.components)
33+
.fill(0)
34+
.map((value, index) => index);
35+
36+
if (image.colorModel === ImageColorModel.GREYA) {
37+
channels = [0];
38+
} else if (image.colorModel === ImageColorModel.RGBA) {
39+
channels = [0, 1, 2];
40+
}
41+
42+
return newImage.level({
43+
inputMin: minMax.min,
44+
inputMax: minMax.max,
45+
outputMin: 0,
46+
outputMax: image.maxValue,
47+
channels,
48+
...options,
49+
});
50+
}

src/filters/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export * from './and';
22
export * from './blur';
33
export * from './convolution';
44
export * from './derivativeFilter';
5+
export * from './enhanceContrast';
56
export * from './gaussianBlur';
67
export * from './gradientFilter';
78
export * from './hypotenuse';

0 commit comments

Comments
 (0)