Initial commit
This commit is contained in:
commit
e49726988c
5445 files changed
+1089914
No files matched your search
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "../src",
|
||||
"module": "nodenext",
|
||||
"moduleResolution": "nodenext"
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"extends": "./build.json",
|
||||
"include": [
|
||||
"../src/**/*.ts",
|
||||
"../src/**/*.cts",
|
||||
"../src/**/*.tsx",
|
||||
"../src/**/*.json"
|
||||
],
|
||||
"exclude": [
|
||||
"../**/*.test.ts",
|
||||
"../src/**/*.mts",
|
||||
"../src/package.json"
|
||||
],
|
||||
"compilerOptions": {
|
||||
"outDir": "../.tshy-build/commonjs"
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"extends": "./build.json",
|
||||
"include": [
|
||||
"../src/**/*.ts",
|
||||
"../src/**/*.mts",
|
||||
"../src/**/*.tsx",
|
||||
"../src/**/*.json"
|
||||
],
|
||||
"exclude": [
|
||||
"../**/*.test.ts",
|
||||
"../src/package.json"
|
||||
],
|
||||
"compilerOptions": {
|
||||
"outDir": "../.tshy-build/esm"
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
|
||||
|
||||
> @jimp/plugin-color@1.5.0 build /Users/andrewlisowski/Documents/jimp/plugins/plugin-color
|
||||
> tshy
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
|
||||
|
||||
> @jimp/plugin-color@1.1.2 lint /Users/andrewlisowski/Documents/jimp/plugins/plugin-color
|
||||
> eslint .
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
|
||||
> @jimp/plugin-color@1.1.1 test:browser /Users/andrewlisowski/Documents/jimp/plugins/plugin-color
|
||||
> vitest --config vitest.config.browser.mjs "--watch=false" "--u"
|
||||
|
||||
|
||||
[7m[1m[36m RUN [39m[22m[27m [36mv1.4.0[39m [90m/Users/andrewlisowski/Documents/jimp/plugins/plugin-color[39m
|
||||
[2m[32m Browser runner started at http://localhost:5173/[39m[22m
|
||||
|
||||
[?25l [90m·[39m [2msrc/[22mnormalize[2m.test.ts[22m[2m (2)[22m
|
||||
[90m·[39m [2msrc/[22mconvolution[2m.test.ts[22m[2m (3)[22m
|
||||
[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[?25l[2K[1A[2K[1A[2K[G [90m·[39m [2msrc/[22mnormalize[2m.test.ts[22m[2m (2)[22m
|
||||
[90m·[39m [2msrc/[22mconvolution[2m.test.ts[22m[2m (3)[22m
|
||||
[90m·[39m [2msrc/[22mindex[2m.test.ts[22m[2m (7)[22m
|
||||
[?25l[2K[1A[2K[1A[2K[1A[2K[G [32m✓[39m [2msrc/[22mnormalize[2m.test.ts[22m[2m (2)[22m
|
||||
[90m·[39m [2msrc/[22mconvolution[2m.test.ts[22m[2m (3)[22m
|
||||
[90m·[39m [2msrc/[22mindex[2m.test.ts[22m[2m (7)[22m
|
||||
[2K[1A[2K[1A[2K[1A[2K[G [32m✓[39m [2msrc/[22mnormalize[2m.test.ts[22m[2m (2)[22m
|
||||
[32m✓[39m [2msrc/[22mconvolution[2m.test.ts[22m[2m (3)[22m
|
||||
[32m✓[39m [2msrc/[22mindex[2m.test.ts[22m[2m (7)[22m
|
||||
|
||||
[2m Test Files [22m [1m[32m3 passed[39m[22m[90m (3)[39m
|
||||
[2m Tests [22m [1m[32m12 passed[39m[22m[90m (12)[39m
|
||||
[2m Start at [22m 00:40:22
|
||||
[2m Duration [22m 3.94s[2m (transform 0ms, setup 0ms, collect 1.07s, tests 13ms, environment 0ms, prepare 0ms)[22m
|
||||
|
||||
[?25h[?25h
|
||||
+1373
File diff suppressed because it is too large.
Load diff
+74
@@ -0,0 +1,74 @@
|
||||
# v1.1.3 (Mon Sep 02 2024)
|
||||
|
||||
#### 🐛 Bug Fix
|
||||
|
||||
- Update deps [#1319](https://github.com/jimp-dev/jimp/pull/1319) ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
||||
|
||||
#### Authors: 1
|
||||
|
||||
- Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
||||
|
||||
---
|
||||
|
||||
# v1.1.2 (Mon Sep 02 2024)
|
||||
|
||||
### Release Notes
|
||||
|
||||
#### Make brightness function behave like other implementations ([#1312](https://github.com/jimp-dev/jimp/pull/1312))
|
||||
|
||||
This PR changes the `brightness` function to behave like the css brightness function and other implementations. Previously it was doing something odd. Instead of multiplying the color channel by the multiplier value, it multiplied against the inversion of the current color.
|
||||
|
||||
In the current version a value of `1` won't change the colors at all. Values above 1 will brighten the colors, values below 1 will darken the colors.
|
||||
|
||||
---
|
||||
|
||||
#### 🐛 Bug Fix
|
||||
|
||||
- Fix pixelate not working well with alpha channel [#1314](https://github.com/jimp-dev/jimp/pull/1314) ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
||||
- Make brightness function behave like other implementations [#1312](https://github.com/jimp-dev/jimp/pull/1312) ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
||||
|
||||
#### Authors: 1
|
||||
|
||||
- Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
||||
|
||||
---
|
||||
|
||||
# v1.1.0 (Sun Sep 01 2024)
|
||||
|
||||
#### ⚠️ Pushed to `main`
|
||||
|
||||
- update more docs ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
||||
|
||||
#### Authors: 1
|
||||
|
||||
- Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
||||
|
||||
---
|
||||
|
||||
# v1.0.3 (Sat Aug 31 2024)
|
||||
|
||||
#### 🐛 Bug Fix
|
||||
|
||||
- Fix build [#1303](https://github.com/jimp-dev/jimp/pull/1303) ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
||||
|
||||
#### ⚠️ Pushed to `main`
|
||||
|
||||
- add clean script ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
||||
|
||||
#### Authors: 1
|
||||
|
||||
- Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
||||
|
||||
---
|
||||
|
||||
# v1.0.2 (Sat Aug 31 2024)
|
||||
|
||||
#### ⚠️ Pushed to `main`
|
||||
|
||||
- set side effects ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
||||
- fix versions ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
||||
- add publish config ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
||||
|
||||
#### Authors: 1
|
||||
|
||||
- Andrew Lisowski ([@hipstersmoothie](https://github.com/hipstersmoothie))
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Oliver Moran
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<div align="center">
|
||||
<img width="200" height="200"
|
||||
src="https://s3.amazonaws.com/pix.iemoji.com/images/emoji/apple/ios-11/256/crayon.png">
|
||||
<h1>@jimp/utils</h1>
|
||||
<p>Utils for jimp extensions.</p>
|
||||
</div>
|
||||
|
||||
- [color](http://jimp-dev.github.io/jimp/api/jimp/classes/jimp#color)
|
||||
- [brightness](http://jimp-dev.github.io/jimp/api/jimp/classes/jimp#brightness)
|
||||
- [contrast](http://jimp-dev.github.io/jimp/api/jimp/classes/jimp#contrast)
|
||||
- [posterize](http://jimp-dev.github.io/jimp/api/jimp/classes/jimp#posterize)
|
||||
- [opacity](http://jimp-dev.github.io/jimp/api/jimp/classes/jimp#opacity)
|
||||
- [sepia](http://jimp-dev.github.io/jimp/api/jimp/classes/jimp#sepia)
|
||||
- [fade](http://jimp-dev.github.io/jimp/api/jimp/classes/jimp#fade)
|
||||
- [convolution](http://jimp-dev.github.io/jimp/api/jimp/classes/jimp#convolution)
|
||||
- [opaque](http://jimp-dev.github.io/jimp/api/jimp/classes/jimp#opaque)
|
||||
- [pixelate](http://jimp-dev.github.io/jimp/api/jimp/classes/jimp#pixelate)
|
||||
- [convolute](http://jimp-dev.github.io/jimp/api/jimp/classes/jimp#convolute)
|
||||
- [normalize](http://jimp-dev.github.io/jimp/api/jimp/classes/jimp#normalize)
|
||||
- [invert](http://jimp-dev.github.io/jimp/api/jimp/classes/jimp#invert)
|
||||
+706
@@ -0,0 +1,706 @@
|
||||
import { Edge, JimpClass } from "@jimp/types";
|
||||
import { z } from "zod";
|
||||
declare const ConvolutionOptionsSchema: z.ZodUnion<[z.ZodArray<z.ZodArray<z.ZodNumber, "many">, "many">, z.ZodObject<{
|
||||
/** a matrix to weight the neighbors sum */
|
||||
kernel: z.ZodArray<z.ZodArray<z.ZodNumber, "many">, "many">;
|
||||
/**define how to sum pixels from outside the border */
|
||||
edgeHandling: z.ZodOptional<z.ZodNativeEnum<typeof Edge>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
kernel: number[][];
|
||||
edgeHandling?: Edge | undefined;
|
||||
}, {
|
||||
kernel: number[][];
|
||||
edgeHandling?: Edge | undefined;
|
||||
}>]>;
|
||||
type ConvolutionOptions = z.infer<typeof ConvolutionOptionsSchema>;
|
||||
declare const ConvoluteOptionsSchema: z.ZodUnion<[z.ZodArray<z.ZodArray<z.ZodNumber, "many">, "many">, z.ZodObject<{
|
||||
/** the convolution kernel */
|
||||
kernel: z.ZodArray<z.ZodArray<z.ZodNumber, "many">, "many">;
|
||||
/** the x position of the region to apply convolution to */
|
||||
x: z.ZodOptional<z.ZodNumber>;
|
||||
/** the y position of the region to apply convolution to */
|
||||
y: z.ZodOptional<z.ZodNumber>;
|
||||
/** the width of the region to apply convolution to */
|
||||
w: z.ZodOptional<z.ZodNumber>;
|
||||
/** the height of the region to apply convolution to */
|
||||
h: z.ZodOptional<z.ZodNumber>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
kernel: number[][];
|
||||
x?: number | undefined;
|
||||
y?: number | undefined;
|
||||
w?: number | undefined;
|
||||
h?: number | undefined;
|
||||
}, {
|
||||
kernel: number[][];
|
||||
x?: number | undefined;
|
||||
y?: number | undefined;
|
||||
w?: number | undefined;
|
||||
h?: number | undefined;
|
||||
}>]>;
|
||||
type ConvoluteOptions = z.infer<typeof ConvoluteOptionsSchema>;
|
||||
declare const PixelateOptionsSchema: z.ZodUnion<[z.ZodNumber, z.ZodObject<{
|
||||
/** the size of the pixels */
|
||||
size: z.ZodNumber;
|
||||
/** the x position of the region to pixelate */
|
||||
x: z.ZodOptional<z.ZodNumber>;
|
||||
/** the y position of the region to pixelate */
|
||||
y: z.ZodOptional<z.ZodNumber>;
|
||||
/** the width of the region to pixelate */
|
||||
w: z.ZodOptional<z.ZodNumber>;
|
||||
/** the height of the region to pixelate */
|
||||
h: z.ZodOptional<z.ZodNumber>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
size: number;
|
||||
x?: number | undefined;
|
||||
y?: number | undefined;
|
||||
w?: number | undefined;
|
||||
h?: number | undefined;
|
||||
}, {
|
||||
size: number;
|
||||
x?: number | undefined;
|
||||
y?: number | undefined;
|
||||
w?: number | undefined;
|
||||
h?: number | undefined;
|
||||
}>]>;
|
||||
type PixelateOptions = z.infer<typeof PixelateOptionsSchema>;
|
||||
declare const HueActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"hue">;
|
||||
params: z.ZodTuple<[z.ZodNumber], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [number];
|
||||
apply: "hue";
|
||||
}, {
|
||||
params: [number];
|
||||
apply: "hue";
|
||||
}>;
|
||||
export type HueAction = z.infer<typeof HueActionSchema>;
|
||||
declare const SpinActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"spin">;
|
||||
params: z.ZodTuple<[z.ZodNumber], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [number];
|
||||
apply: "spin";
|
||||
}, {
|
||||
params: [number];
|
||||
apply: "spin";
|
||||
}>;
|
||||
export type SpinAction = z.infer<typeof SpinActionSchema>;
|
||||
declare const LightenActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"lighten">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "lighten";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "lighten";
|
||||
params?: [number] | undefined;
|
||||
}>;
|
||||
export type LightenAction = z.infer<typeof LightenActionSchema>;
|
||||
declare const MixActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"mix">;
|
||||
params: z.ZodUnion<[z.ZodTuple<[z.ZodObject<{
|
||||
r: z.ZodNumber;
|
||||
g: z.ZodNumber;
|
||||
b: z.ZodNumber;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}>], null>, z.ZodTuple<[z.ZodObject<{
|
||||
r: z.ZodNumber;
|
||||
g: z.ZodNumber;
|
||||
b: z.ZodNumber;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}>, z.ZodNumber], null>]>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}] | [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}, number];
|
||||
apply: "mix";
|
||||
}, {
|
||||
params: [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}] | [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}, number];
|
||||
apply: "mix";
|
||||
}>;
|
||||
export type MixAction = z.infer<typeof MixActionSchema>;
|
||||
declare const TintActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"tint">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "tint";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "tint";
|
||||
params?: [number] | undefined;
|
||||
}>;
|
||||
export type TintAction = z.infer<typeof TintActionSchema>;
|
||||
declare const ShadeActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"shade">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "shade";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "shade";
|
||||
params?: [number] | undefined;
|
||||
}>;
|
||||
export type ShadeAction = z.infer<typeof ShadeActionSchema>;
|
||||
declare const XorActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"xor">;
|
||||
params: z.ZodTuple<[z.ZodObject<{
|
||||
r: z.ZodNumber;
|
||||
g: z.ZodNumber;
|
||||
b: z.ZodNumber;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}>], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}];
|
||||
apply: "xor";
|
||||
}, {
|
||||
params: [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}];
|
||||
apply: "xor";
|
||||
}>;
|
||||
export type XorAction = z.infer<typeof XorActionSchema>;
|
||||
declare const RedActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"red">;
|
||||
params: z.ZodTuple<[z.ZodNumber], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [number];
|
||||
apply: "red";
|
||||
}, {
|
||||
params: [number];
|
||||
apply: "red";
|
||||
}>;
|
||||
export type RedAction = z.infer<typeof RedActionSchema>;
|
||||
declare const GreenActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"green">;
|
||||
params: z.ZodTuple<[z.ZodNumber], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [number];
|
||||
apply: "green";
|
||||
}, {
|
||||
params: [number];
|
||||
apply: "green";
|
||||
}>;
|
||||
export type GreenAction = z.infer<typeof GreenActionSchema>;
|
||||
declare const BlueActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"blue">;
|
||||
params: z.ZodTuple<[z.ZodNumber], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [number];
|
||||
apply: "blue";
|
||||
}, {
|
||||
params: [number];
|
||||
apply: "blue";
|
||||
}>;
|
||||
export type BlueAction = z.infer<typeof BlueActionSchema>;
|
||||
declare const BrightenActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"brighten">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "brighten";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "brighten";
|
||||
params?: [number] | undefined;
|
||||
}>;
|
||||
export type BrightenAction = z.infer<typeof BrightenActionSchema>;
|
||||
declare const DarkenActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"darken">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "darken";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "darken";
|
||||
params?: [number] | undefined;
|
||||
}>;
|
||||
export type DarkenAction = z.infer<typeof DarkenActionSchema>;
|
||||
declare const DesaturateActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"desaturate">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "desaturate";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "desaturate";
|
||||
params?: [number] | undefined;
|
||||
}>;
|
||||
export type DesaturateAction = z.infer<typeof DesaturateActionSchema>;
|
||||
declare const SaturateActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"saturate">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "saturate";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "saturate";
|
||||
params?: [number] | undefined;
|
||||
}>;
|
||||
export type SaturateAction = z.infer<typeof SaturateActionSchema>;
|
||||
declare const GrayscaleActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"greyscale">;
|
||||
params: z.ZodOptional<z.ZodTuple<[], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "greyscale";
|
||||
params?: [] | undefined;
|
||||
}, {
|
||||
apply: "greyscale";
|
||||
params?: [] | undefined;
|
||||
}>;
|
||||
export type GrayscaleAction = z.infer<typeof GrayscaleActionSchema>;
|
||||
declare const ColorActionNameSchema: z.ZodUnion<[z.ZodObject<{
|
||||
apply: z.ZodLiteral<"hue">;
|
||||
params: z.ZodTuple<[z.ZodNumber], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [number];
|
||||
apply: "hue";
|
||||
}, {
|
||||
params: [number];
|
||||
apply: "hue";
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"spin">;
|
||||
params: z.ZodTuple<[z.ZodNumber], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [number];
|
||||
apply: "spin";
|
||||
}, {
|
||||
params: [number];
|
||||
apply: "spin";
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"lighten">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "lighten";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "lighten";
|
||||
params?: [number] | undefined;
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"mix">;
|
||||
params: z.ZodUnion<[z.ZodTuple<[z.ZodObject<{
|
||||
r: z.ZodNumber;
|
||||
g: z.ZodNumber;
|
||||
b: z.ZodNumber;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}>], null>, z.ZodTuple<[z.ZodObject<{
|
||||
r: z.ZodNumber;
|
||||
g: z.ZodNumber;
|
||||
b: z.ZodNumber;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}>, z.ZodNumber], null>]>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}] | [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}, number];
|
||||
apply: "mix";
|
||||
}, {
|
||||
params: [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}] | [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}, number];
|
||||
apply: "mix";
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"tint">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "tint";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "tint";
|
||||
params?: [number] | undefined;
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"shade">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "shade";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "shade";
|
||||
params?: [number] | undefined;
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"xor">;
|
||||
params: z.ZodTuple<[z.ZodObject<{
|
||||
r: z.ZodNumber;
|
||||
g: z.ZodNumber;
|
||||
b: z.ZodNumber;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}>], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}];
|
||||
apply: "xor";
|
||||
}, {
|
||||
params: [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}];
|
||||
apply: "xor";
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"red">;
|
||||
params: z.ZodTuple<[z.ZodNumber], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [number];
|
||||
apply: "red";
|
||||
}, {
|
||||
params: [number];
|
||||
apply: "red";
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"green">;
|
||||
params: z.ZodTuple<[z.ZodNumber], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [number];
|
||||
apply: "green";
|
||||
}, {
|
||||
params: [number];
|
||||
apply: "green";
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"blue">;
|
||||
params: z.ZodTuple<[z.ZodNumber], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [number];
|
||||
apply: "blue";
|
||||
}, {
|
||||
params: [number];
|
||||
apply: "blue";
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"brighten">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "brighten";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "brighten";
|
||||
params?: [number] | undefined;
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"darken">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "darken";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "darken";
|
||||
params?: [number] | undefined;
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"desaturate">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "desaturate";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "desaturate";
|
||||
params?: [number] | undefined;
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"saturate">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "saturate";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "saturate";
|
||||
params?: [number] | undefined;
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"greyscale">;
|
||||
params: z.ZodOptional<z.ZodTuple<[], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "greyscale";
|
||||
params?: [] | undefined;
|
||||
}, {
|
||||
apply: "greyscale";
|
||||
params?: [] | undefined;
|
||||
}>]>;
|
||||
export type ColorAction = z.infer<typeof ColorActionNameSchema>;
|
||||
export declare const ColorActionName: Readonly<{
|
||||
LIGHTEN: "lighten";
|
||||
BRIGHTEN: "brighten";
|
||||
DARKEN: "darken";
|
||||
DESATURATE: "desaturate";
|
||||
SATURATE: "saturate";
|
||||
GREYSCALE: "greyscale";
|
||||
SPIN: "spin";
|
||||
HUE: "hue";
|
||||
MIX: "mix";
|
||||
TINT: "tint";
|
||||
SHADE: "shade";
|
||||
XOR: "xor";
|
||||
RED: "red";
|
||||
GREEN: "green";
|
||||
BLUE: "blue";
|
||||
}>;
|
||||
export declare const methods: {
|
||||
/**
|
||||
* Normalizes the image.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.normalize();
|
||||
* ```
|
||||
*/
|
||||
normalize<I extends JimpClass>(image: I): I;
|
||||
/**
|
||||
* Inverts the colors in the image.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.invert();
|
||||
* ```
|
||||
*/
|
||||
invert<I extends JimpClass>(image: I): I;
|
||||
/**
|
||||
* Adjusts the brightness of the image
|
||||
* @param val the amount to adjust the brightness.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.brightness(0.5);
|
||||
* ```
|
||||
*/
|
||||
brightness<I extends JimpClass>(image: I, val: number): I;
|
||||
/**
|
||||
* Adjusts the contrast of the image
|
||||
* @param val the amount to adjust the contrast, a number between -1 and +1
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.contrast(0.75);
|
||||
* ```
|
||||
*/
|
||||
contrast<I extends JimpClass>(image: I, val: number): I;
|
||||
/**
|
||||
* Apply a posterize effect
|
||||
* @param n the amount to adjust the contrast, minimum threshold is two
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.posterize(5);
|
||||
* ```
|
||||
*/
|
||||
posterize<I extends JimpClass>(image: I, n: number): I;
|
||||
/**
|
||||
* Removes colour from the image using ITU Rec 709 luminance values
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.greyscale();
|
||||
* ```
|
||||
*/
|
||||
greyscale<I extends JimpClass>(image: I): I;
|
||||
/**
|
||||
* Multiplies the opacity of each pixel by a factor between 0 and 1
|
||||
* @param f A number, the factor by which to multiply the opacity of each pixel
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.opacity(0.5);
|
||||
* ```
|
||||
*/
|
||||
opacity<I extends JimpClass>(image: I, f: number): I;
|
||||
/**
|
||||
* Applies a sepia tone to the image.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.sepia();
|
||||
* ```
|
||||
*/
|
||||
sepia<I extends JimpClass>(image: I): I;
|
||||
/**
|
||||
* Fades each pixel by a factor between 0 and 1
|
||||
* @param f A number from 0 to 1. 0 will haven no effect. 1 will turn the image completely transparent.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.fade(0.7);
|
||||
* ```
|
||||
*/
|
||||
fade<I extends JimpClass>(image: I, f: number): I;
|
||||
/**
|
||||
* Adds each element of the image to its local neighbors, weighted by the kernel
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.convolute([
|
||||
* [-1, -1, 0],
|
||||
* [-1, 1, 1],
|
||||
* [0, 1, 1],
|
||||
* ]);
|
||||
* ```
|
||||
*/
|
||||
convolution<I extends JimpClass>(image: I, options: ConvolutionOptions): I;
|
||||
/**
|
||||
* Set the alpha channel on every pixel to fully opaque.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.opaque();
|
||||
* ```
|
||||
*/
|
||||
opaque<I extends JimpClass>(image: I): I;
|
||||
/**
|
||||
* Pixelates the image or a region
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* // pixelate the whole image
|
||||
* image.pixelate(10);
|
||||
*
|
||||
* // pixelate a region
|
||||
* image.pixelate(10, 10, 10, 20, 20);
|
||||
* ```
|
||||
*/
|
||||
pixelate<I extends JimpClass>(image: I, options: PixelateOptions): I;
|
||||
/**
|
||||
* Applies a convolution kernel to the image or a region
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* // apply a convolution kernel to the whole image
|
||||
* image.convolution([
|
||||
* [-1, -1, 0],
|
||||
* [-1, 1, 1],
|
||||
* [0, 1, 1],
|
||||
* ]);
|
||||
*
|
||||
* // apply a convolution kernel to a region
|
||||
* image.convolution([
|
||||
* [-1, -1, 0],
|
||||
* [-1, 1, 1],
|
||||
* [0, 1, 1],
|
||||
* ], 10, 10, 10, 20);
|
||||
* ```
|
||||
*/
|
||||
convolute<I extends JimpClass>(image: I, options: ConvoluteOptions): I;
|
||||
/**
|
||||
* Apply multiple color modification rules
|
||||
* @param actions list of color modification rules, in following format: { apply: '<rule-name>', params: [ <rule-parameters> ] }
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.color([
|
||||
* { apply: "hue", params: [-90] },
|
||||
* { apply: "lighten", params: [50] },
|
||||
* { apply: "xor", params: ["#06D"] },
|
||||
* ]);
|
||||
* ```
|
||||
*/
|
||||
color<I extends JimpClass>(image: I, actions: ColorAction[]): I;
|
||||
};
|
||||
export {};
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,SAAS,EAAY,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,QAAA,MAAM,wBAAwB;IAL5B,2CAA2C;;IAE3C,sDAAsD;;;;;;;;IAMtD,CAAC;AAEH,KAAK,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAcnE,QAAA,MAAM,sBAAsB;IAX1B,6BAA6B;;IAE7B,2DAA2D;;IAE3D,2DAA2D;;IAE3D,sDAAsD;;IAEtD,uDAAuD;;;;;;;;;;;;;;IAMvD,CAAC;AAGH,KAAK,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAe/D,QAAA,MAAM,qBAAqB;IAXzB,6BAA6B;;IAE7B,+CAA+C;;IAE/C,+CAA+C;;IAE/C,0CAA0C;;IAE1C,2CAA2C;;;;;;;;;;;;;;IAM3C,CAAC;AAGH,KAAK,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAiC7D,QAAA,MAAM,eAAe;;;;;;;;;EAGnB,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,QAAA,MAAM,gBAAgB;;;;;;;;;EAGpB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,QAAA,MAAM,mBAAmB;;;;;;;;;EAGvB,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAQhE,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAMnB,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,QAAA,MAAM,gBAAgB;;;;;;;;;EAGpB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,QAAA,MAAM,iBAAiB;;;;;;;;;EAGrB,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGnB,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,QAAA,MAAM,eAAe;;;;;;;;;EAGnB,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,QAAA,MAAM,iBAAiB;;;;;;;;;EAGrB,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,QAAA,MAAM,gBAAgB;;;;;;;;;EAGpB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,QAAA,MAAM,oBAAoB;;;;;;;;;EAGxB,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,QAAA,MAAM,kBAAkB;;;;;;;;;EAGtB,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,QAAA,MAAM,sBAAsB;;;;;;;;;EAG1B,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,QAAA,MAAM,oBAAoB;;;;;;;;;EAGxB,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,QAAA,MAAM,qBAAqB;;;;;;;;;EAGzB,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,QAAA,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAgBzB,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEhE,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;EAgB1B,CAAC;AA2CH,eAAO,MAAM,OAAO;IAClB;;;;;;;;;;OAUG;cACO,CAAC,SAAS,SAAS,SAAS,CAAC;IAoCvC;;;;;;;;;;OAUG;WACI,CAAC,SAAS,SAAS,SAAS,CAAC;IAUpC;;;;;;;;;;;OAWG;eACQ,CAAC,SAAS,SAAS,SAAS,CAAC,OAAO,MAAM;IAcrD;;;;;;;;;;;OAWG;aACM,CAAC,SAAS,SAAS,SAAS,CAAC,OAAO,MAAM;IAyBnD;;;;;;;;;;;OAWG;cACO,CAAC,SAAS,SAAS,SAAS,CAAC,KAAK,MAAM;IA0BlD;;;;;;;;;;OAUG;cACO,CAAC,SAAS,SAAS,SAAS,CAAC;IAqBvC;;;;;;;;;;;OAWG;YACK,CAAC,SAAS,SAAS,SAAS,CAAC,KAAK,MAAM;IAiBhD;;;;;;;;;;OAUG;UACG,CAAC,SAAS,SAAS,SAAS,CAAC;IAkBnC;;;;;;;;;;;OAWG;SACE,CAAC,SAAS,SAAS,SAAS,CAAC,KAAK,MAAM;IAa7C;;;;;;;;;;;;;;OAcG;gBACS,CAAC,SAAS,SAAS,SAAS,CAAC,WAAW,kBAAkB;IA0FtE;;;;;;;;;;OAUG;WACI,CAAC,SAAS,SAAS,SAAS,CAAC;IAQpC;;;;;;;;;;;;;;OAcG;aACM,CAAC,SAAS,SAAS,SAAS,CAAC,WAAW,eAAe;IAmChE;;;;;;;;;;;;;;;;;;;;;;OAsBG;cACO,CAAC,SAAS,SAAS,SAAS,CAAC,WAAW,gBAAgB;IA0BlE;;;;;;;;;;;;;;;OAeG;UACG,CAAC,SAAS,SAAS,SAAS,CAAC,WAAW,WAAW,EAAE;CAsE5D,CAAC"}
|
||||
+713
@@ -0,0 +1,713 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.methods = exports.ColorActionName = void 0;
|
||||
const tinycolor2_1 = __importDefault(require("tinycolor2"));
|
||||
const utils_1 = require("@jimp/utils");
|
||||
const types_1 = require("@jimp/types");
|
||||
const zod_1 = require("zod");
|
||||
const ConvolutionMatrixSchema = zod_1.z.array(zod_1.z.number()).min(1).array();
|
||||
const ConvolutionComplexOptionsSchema = zod_1.z.object({
|
||||
/** a matrix to weight the neighbors sum */
|
||||
kernel: ConvolutionMatrixSchema,
|
||||
/**define how to sum pixels from outside the border */
|
||||
edgeHandling: zod_1.z.nativeEnum(types_1.Edge).optional(),
|
||||
});
|
||||
const ConvolutionOptionsSchema = zod_1.z.union([
|
||||
ConvolutionMatrixSchema,
|
||||
ConvolutionComplexOptionsSchema,
|
||||
]);
|
||||
const ConvoluteComplexOptionsSchema = zod_1.z.object({
|
||||
/** the convolution kernel */
|
||||
kernel: ConvolutionMatrixSchema,
|
||||
/** the x position of the region to apply convolution to */
|
||||
x: zod_1.z.number().optional(),
|
||||
/** the y position of the region to apply convolution to */
|
||||
y: zod_1.z.number().optional(),
|
||||
/** the width of the region to apply convolution to */
|
||||
w: zod_1.z.number().optional(),
|
||||
/** the height of the region to apply convolution to */
|
||||
h: zod_1.z.number().optional(),
|
||||
});
|
||||
const ConvoluteOptionsSchema = zod_1.z.union([
|
||||
ConvolutionMatrixSchema,
|
||||
ConvoluteComplexOptionsSchema,
|
||||
]);
|
||||
const PixelateSize = zod_1.z.number().min(1).max(Infinity);
|
||||
const PixelateComplexOptionsSchema = zod_1.z.object({
|
||||
/** the size of the pixels */
|
||||
size: PixelateSize,
|
||||
/** the x position of the region to pixelate */
|
||||
x: zod_1.z.number().optional(),
|
||||
/** the y position of the region to pixelate */
|
||||
y: zod_1.z.number().optional(),
|
||||
/** the width of the region to pixelate */
|
||||
w: zod_1.z.number().optional(),
|
||||
/** the height of the region to pixelate */
|
||||
h: zod_1.z.number().optional(),
|
||||
});
|
||||
const PixelateOptionsSchema = zod_1.z.union([
|
||||
PixelateSize,
|
||||
PixelateComplexOptionsSchema,
|
||||
]);
|
||||
function applyKernel(image, kernel, x, y) {
|
||||
const value = [0, 0, 0, 0];
|
||||
const size = (kernel.length - 1) / 2;
|
||||
for (let kx = 0; kx < kernel.length; kx += 1) {
|
||||
for (let ky = 0; ky < kernel[kx].length; ky += 1) {
|
||||
const idx = image.getPixelIndex(x + kx - size, y + ky - size);
|
||||
value[0] += image.bitmap.data[idx] * kernel[kx][ky];
|
||||
value[1] += image.bitmap.data[idx + 1] * kernel[kx][ky];
|
||||
value[2] += image.bitmap.data[idx + 2] * kernel[kx][ky];
|
||||
value[3] += image.bitmap.data[idx + 3] * kernel[kx][ky];
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
function mix(clr, clr2, p = 50) {
|
||||
return {
|
||||
r: (clr2.r - clr.r) * (p / 100) + clr.r,
|
||||
g: (clr2.g - clr.g) * (p / 100) + clr.g,
|
||||
b: (clr2.b - clr.b) * (p / 100) + clr.b,
|
||||
};
|
||||
}
|
||||
const HueActionSchema = zod_1.z.object({
|
||||
apply: zod_1.z.literal("hue"),
|
||||
params: zod_1.z.tuple([zod_1.z.number().min(-360).max(360)]),
|
||||
});
|
||||
const SpinActionSchema = zod_1.z.object({
|
||||
apply: zod_1.z.literal("spin"),
|
||||
params: zod_1.z.tuple([zod_1.z.number().min(-360).max(360)]),
|
||||
});
|
||||
const LightenActionSchema = zod_1.z.object({
|
||||
apply: zod_1.z.literal("lighten"),
|
||||
params: zod_1.z.tuple([zod_1.z.number().min(0).max(100)]).optional(),
|
||||
});
|
||||
const RGBColorSchema = zod_1.z.object({
|
||||
r: zod_1.z.number().min(0).max(255),
|
||||
g: zod_1.z.number().min(0).max(255),
|
||||
b: zod_1.z.number().min(0).max(255),
|
||||
});
|
||||
const MixActionSchema = zod_1.z.object({
|
||||
apply: zod_1.z.literal("mix"),
|
||||
params: zod_1.z.union([
|
||||
zod_1.z.tuple([RGBColorSchema]),
|
||||
zod_1.z.tuple([RGBColorSchema, zod_1.z.number().min(0).max(100)]),
|
||||
]),
|
||||
});
|
||||
const TintActionSchema = zod_1.z.object({
|
||||
apply: zod_1.z.literal("tint"),
|
||||
params: zod_1.z.tuple([zod_1.z.number().min(0).max(100)]).optional(),
|
||||
});
|
||||
const ShadeActionSchema = zod_1.z.object({
|
||||
apply: zod_1.z.literal("shade"),
|
||||
params: zod_1.z.tuple([zod_1.z.number().min(0).max(100)]).optional(),
|
||||
});
|
||||
const XorActionSchema = zod_1.z.object({
|
||||
apply: zod_1.z.literal("xor"),
|
||||
params: zod_1.z.tuple([RGBColorSchema]),
|
||||
});
|
||||
const RedActionSchema = zod_1.z.object({
|
||||
apply: zod_1.z.literal("red"),
|
||||
params: zod_1.z.tuple([zod_1.z.number().min(-255).max(255)]),
|
||||
});
|
||||
const GreenActionSchema = zod_1.z.object({
|
||||
apply: zod_1.z.literal("green"),
|
||||
params: zod_1.z.tuple([zod_1.z.number().min(-255).max(255)]),
|
||||
});
|
||||
const BlueActionSchema = zod_1.z.object({
|
||||
apply: zod_1.z.literal("blue"),
|
||||
params: zod_1.z.tuple([zod_1.z.number().min(-255).max(255)]),
|
||||
});
|
||||
const BrightenActionSchema = zod_1.z.object({
|
||||
apply: zod_1.z.literal("brighten"),
|
||||
params: zod_1.z.tuple([zod_1.z.number().min(0).max(100)]).optional(),
|
||||
});
|
||||
const DarkenActionSchema = zod_1.z.object({
|
||||
apply: zod_1.z.literal("darken"),
|
||||
params: zod_1.z.tuple([zod_1.z.number().min(0).max(100)]).optional(),
|
||||
});
|
||||
const DesaturateActionSchema = zod_1.z.object({
|
||||
apply: zod_1.z.literal("desaturate"),
|
||||
params: zod_1.z.tuple([zod_1.z.number().min(0).max(100)]).optional(),
|
||||
});
|
||||
const SaturateActionSchema = zod_1.z.object({
|
||||
apply: zod_1.z.literal("saturate"),
|
||||
params: zod_1.z.tuple([zod_1.z.number().min(0).max(100)]).optional(),
|
||||
});
|
||||
const GrayscaleActionSchema = zod_1.z.object({
|
||||
apply: zod_1.z.literal("greyscale"),
|
||||
params: zod_1.z.tuple([]).optional(),
|
||||
});
|
||||
const ColorActionNameSchema = zod_1.z.union([
|
||||
HueActionSchema,
|
||||
SpinActionSchema,
|
||||
LightenActionSchema,
|
||||
MixActionSchema,
|
||||
TintActionSchema,
|
||||
ShadeActionSchema,
|
||||
XorActionSchema,
|
||||
RedActionSchema,
|
||||
GreenActionSchema,
|
||||
BlueActionSchema,
|
||||
BrightenActionSchema,
|
||||
DarkenActionSchema,
|
||||
DesaturateActionSchema,
|
||||
SaturateActionSchema,
|
||||
GrayscaleActionSchema,
|
||||
]);
|
||||
exports.ColorActionName = Object.freeze({
|
||||
LIGHTEN: "lighten",
|
||||
BRIGHTEN: "brighten",
|
||||
DARKEN: "darken",
|
||||
DESATURATE: "desaturate",
|
||||
SATURATE: "saturate",
|
||||
GREYSCALE: "greyscale",
|
||||
SPIN: "spin",
|
||||
HUE: "hue",
|
||||
MIX: "mix",
|
||||
TINT: "tint",
|
||||
SHADE: "shade",
|
||||
XOR: "xor",
|
||||
RED: "red",
|
||||
GREEN: "green",
|
||||
BLUE: "blue",
|
||||
});
|
||||
/**
|
||||
* Get an image's histogram
|
||||
* @return An object with an array of color occurrence counts for each channel (r,g,b)
|
||||
*/
|
||||
function histogram(image) {
|
||||
const histogram = {
|
||||
r: new Array(256).fill(0),
|
||||
g: new Array(256).fill(0),
|
||||
b: new Array(256).fill(0),
|
||||
};
|
||||
image.scan((_, __, index) => {
|
||||
histogram.r[image.bitmap.data[index + 0]]++;
|
||||
histogram.g[image.bitmap.data[index + 1]]++;
|
||||
histogram.b[image.bitmap.data[index + 2]]++;
|
||||
});
|
||||
return histogram;
|
||||
}
|
||||
/**
|
||||
* Normalize values
|
||||
* @param value Pixel channel value.
|
||||
* @param min Minimum value for channel
|
||||
* @param max Maximum value for channel
|
||||
*/
|
||||
const normalizeValue = function (value, min, max) {
|
||||
return ((value - min) * 255) / (max - min);
|
||||
};
|
||||
const getBounds = function (histogramChannel) {
|
||||
return [
|
||||
histogramChannel.findIndex((value) => value > 0),
|
||||
255 -
|
||||
histogramChannel
|
||||
.slice()
|
||||
.reverse()
|
||||
.findIndex((value) => value > 0),
|
||||
];
|
||||
};
|
||||
exports.methods = {
|
||||
/**
|
||||
* Normalizes the image.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.normalize();
|
||||
* ```
|
||||
*/
|
||||
normalize(image) {
|
||||
const h = histogram(image);
|
||||
// store bounds (minimum and maximum values)
|
||||
const bounds = {
|
||||
r: getBounds(h.r),
|
||||
g: getBounds(h.g),
|
||||
b: getBounds(h.b),
|
||||
};
|
||||
// apply value transformations
|
||||
image.scan((_, __, idx) => {
|
||||
const r = image.bitmap.data[idx + 0];
|
||||
const g = image.bitmap.data[idx + 1];
|
||||
const b = image.bitmap.data[idx + 2];
|
||||
image.bitmap.data[idx + 0] = normalizeValue(r, bounds.r[0], bounds.r[1]);
|
||||
image.bitmap.data[idx + 1] = normalizeValue(g, bounds.g[0], bounds.g[1]);
|
||||
image.bitmap.data[idx + 2] = normalizeValue(b, bounds.b[0], bounds.b[1]);
|
||||
});
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Inverts the colors in the image.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.invert();
|
||||
* ```
|
||||
*/
|
||||
invert(image) {
|
||||
image.scan((_, __, idx) => {
|
||||
image.bitmap.data[idx] = 255 - image.bitmap.data[idx];
|
||||
image.bitmap.data[idx + 1] = 255 - image.bitmap.data[idx + 1];
|
||||
image.bitmap.data[idx + 2] = 255 - image.bitmap.data[idx + 2];
|
||||
});
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Adjusts the brightness of the image
|
||||
* @param val the amount to adjust the brightness.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.brightness(0.5);
|
||||
* ```
|
||||
*/
|
||||
brightness(image, val) {
|
||||
if (typeof val !== "number") {
|
||||
throw new Error("val must be numbers");
|
||||
}
|
||||
image.scan((_, __, idx) => {
|
||||
image.bitmap.data[idx] = (0, utils_1.limit255)(image.bitmap.data[idx] * val);
|
||||
image.bitmap.data[idx + 1] = (0, utils_1.limit255)(image.bitmap.data[idx + 1] * val);
|
||||
image.bitmap.data[idx + 2] = (0, utils_1.limit255)(image.bitmap.data[idx + 2] * val);
|
||||
});
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Adjusts the contrast of the image
|
||||
* @param val the amount to adjust the contrast, a number between -1 and +1
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.contrast(0.75);
|
||||
* ```
|
||||
*/
|
||||
contrast(image, val) {
|
||||
if (typeof val !== "number") {
|
||||
throw new Error("val must be numbers");
|
||||
}
|
||||
if (val < -1 || val > +1) {
|
||||
throw new Error("val must be a number between -1 and +1");
|
||||
}
|
||||
const factor = (val + 1) / (1 - val);
|
||||
function adjust(value) {
|
||||
value = Math.floor(factor * (value - 127) + 127);
|
||||
return value < 0 ? 0 : value > 255 ? 255 : value;
|
||||
}
|
||||
image.scan((_, __, idx) => {
|
||||
image.bitmap.data[idx] = adjust(image.bitmap.data[idx]);
|
||||
image.bitmap.data[idx + 1] = adjust(image.bitmap.data[idx + 1]);
|
||||
image.bitmap.data[idx + 2] = adjust(image.bitmap.data[idx + 2]);
|
||||
});
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Apply a posterize effect
|
||||
* @param n the amount to adjust the contrast, minimum threshold is two
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.posterize(5);
|
||||
* ```
|
||||
*/
|
||||
posterize(image, n) {
|
||||
if (typeof n !== "number") {
|
||||
throw new Error("n must be numbers");
|
||||
}
|
||||
// minimum of 2 levels
|
||||
if (n < 2) {
|
||||
n = 2;
|
||||
}
|
||||
image.scan((_, __, idx) => {
|
||||
const r = image.bitmap.data[idx];
|
||||
const g = image.bitmap.data[idx + 1];
|
||||
const b = image.bitmap.data[idx + 2];
|
||||
image.bitmap.data[idx] =
|
||||
(Math.floor((r / 255) * (n - 1)) / (n - 1)) * 255;
|
||||
image.bitmap.data[idx + 1] =
|
||||
(Math.floor((g / 255) * (n - 1)) / (n - 1)) * 255;
|
||||
image.bitmap.data[idx + 2] =
|
||||
(Math.floor((b / 255) * (n - 1)) / (n - 1)) * 255;
|
||||
});
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Removes colour from the image using ITU Rec 709 luminance values
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.greyscale();
|
||||
* ```
|
||||
*/
|
||||
greyscale(image) {
|
||||
image.scan((_, __, idx) => {
|
||||
// const grey = parseInt(
|
||||
// 0.2126 * image.bitmap.data[idx]! +
|
||||
// 0.7152 * image.bitmap.data[idx + 1]! +
|
||||
// 0.0722 * image.bitmap.data[idx + 2]!,
|
||||
// 10
|
||||
// );
|
||||
const grey = 0.2126 * image.bitmap.data[idx] +
|
||||
0.7152 * image.bitmap.data[idx + 1] +
|
||||
0.0722 * image.bitmap.data[idx + 2];
|
||||
image.bitmap.data[idx] = grey;
|
||||
image.bitmap.data[idx + 1] = grey;
|
||||
image.bitmap.data[idx + 2] = grey;
|
||||
});
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Multiplies the opacity of each pixel by a factor between 0 and 1
|
||||
* @param f A number, the factor by which to multiply the opacity of each pixel
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.opacity(0.5);
|
||||
* ```
|
||||
*/
|
||||
opacity(image, f) {
|
||||
if (typeof f !== "number") {
|
||||
throw new Error("f must be a number");
|
||||
}
|
||||
if (f < 0 || f > 1) {
|
||||
throw new Error("f must be a number from 0 to 1");
|
||||
}
|
||||
image.scan((_, __, idx) => {
|
||||
const v = image.bitmap.data[idx + 3] * f;
|
||||
image.bitmap.data[idx + 3] = v;
|
||||
});
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Applies a sepia tone to the image.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.sepia();
|
||||
* ```
|
||||
*/
|
||||
sepia(image) {
|
||||
image.scan((_, __, idx) => {
|
||||
let red = image.bitmap.data[idx];
|
||||
let green = image.bitmap.data[idx + 1];
|
||||
let blue = image.bitmap.data[idx + 2];
|
||||
red = red * 0.393 + green * 0.769 + blue * 0.189;
|
||||
green = red * 0.349 + green * 0.686 + blue * 0.168;
|
||||
blue = red * 0.272 + green * 0.534 + blue * 0.131;
|
||||
image.bitmap.data[idx] = red < 255 ? red : 255;
|
||||
image.bitmap.data[idx + 1] = green < 255 ? green : 255;
|
||||
image.bitmap.data[idx + 2] = blue < 255 ? blue : 255;
|
||||
});
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Fades each pixel by a factor between 0 and 1
|
||||
* @param f A number from 0 to 1. 0 will haven no effect. 1 will turn the image completely transparent.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.fade(0.7);
|
||||
* ```
|
||||
*/
|
||||
fade(image, f) {
|
||||
if (typeof f !== "number") {
|
||||
throw new Error("f must be a number");
|
||||
}
|
||||
if (f < 0 || f > 1) {
|
||||
throw new Error("f must be a number from 0 to 1");
|
||||
}
|
||||
// this method is an alternative to opacity (which may be deprecated)
|
||||
return this.opacity(image, 1 - f);
|
||||
},
|
||||
/**
|
||||
* Adds each element of the image to its local neighbors, weighted by the kernel
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.convolute([
|
||||
* [-1, -1, 0],
|
||||
* [-1, 1, 1],
|
||||
* [0, 1, 1],
|
||||
* ]);
|
||||
* ```
|
||||
*/
|
||||
convolution(image, options) {
|
||||
const parsed = ConvolutionOptionsSchema.parse(options);
|
||||
const { kernel, edgeHandling = types_1.Edge.EXTEND } = "kernel" in parsed ? parsed : { kernel: parsed, edgeHandling: undefined };
|
||||
if (!kernel[0]) {
|
||||
throw new Error("kernel must be a matrix");
|
||||
}
|
||||
const newData = Buffer.from(image.bitmap.data);
|
||||
const kRows = kernel.length;
|
||||
const kCols = kernel[0].length;
|
||||
const rowEnd = Math.floor(kRows / 2);
|
||||
const colEnd = Math.floor(kCols / 2);
|
||||
const rowIni = -rowEnd;
|
||||
const colIni = -colEnd;
|
||||
let weight;
|
||||
let rSum;
|
||||
let gSum;
|
||||
let bSum;
|
||||
let ri;
|
||||
let gi;
|
||||
let bi;
|
||||
let xi;
|
||||
let yi;
|
||||
let idxi;
|
||||
image.scan((x, y, idx) => {
|
||||
bSum = 0;
|
||||
gSum = 0;
|
||||
rSum = 0;
|
||||
for (let row = rowIni; row <= rowEnd; row++) {
|
||||
for (let col = colIni; col <= colEnd; col++) {
|
||||
xi = x + col;
|
||||
yi = y + row;
|
||||
weight = kernel[row + rowEnd][col + colEnd];
|
||||
idxi = image.getPixelIndex(xi, yi, edgeHandling);
|
||||
if (idxi === -1) {
|
||||
bi = 0;
|
||||
gi = 0;
|
||||
ri = 0;
|
||||
}
|
||||
else {
|
||||
ri = image.bitmap.data[idxi + 0];
|
||||
gi = image.bitmap.data[idxi + 1];
|
||||
bi = image.bitmap.data[idxi + 2];
|
||||
}
|
||||
rSum += weight * ri;
|
||||
gSum += weight * gi;
|
||||
bSum += weight * bi;
|
||||
}
|
||||
}
|
||||
if (rSum < 0) {
|
||||
rSum = 0;
|
||||
}
|
||||
if (gSum < 0) {
|
||||
gSum = 0;
|
||||
}
|
||||
if (bSum < 0) {
|
||||
bSum = 0;
|
||||
}
|
||||
if (rSum > 255) {
|
||||
rSum = 255;
|
||||
}
|
||||
if (gSum > 255) {
|
||||
gSum = 255;
|
||||
}
|
||||
if (bSum > 255) {
|
||||
bSum = 255;
|
||||
}
|
||||
newData[idx + 0] = rSum;
|
||||
newData[idx + 1] = gSum;
|
||||
newData[idx + 2] = bSum;
|
||||
});
|
||||
image.bitmap.data = newData;
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Set the alpha channel on every pixel to fully opaque.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.opaque();
|
||||
* ```
|
||||
*/
|
||||
opaque(image) {
|
||||
image.scan((_, __, idx) => {
|
||||
image.bitmap.data[idx + 3] = 255;
|
||||
});
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Pixelates the image or a region
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* // pixelate the whole image
|
||||
* image.pixelate(10);
|
||||
*
|
||||
* // pixelate a region
|
||||
* image.pixelate(10, 10, 10, 20, 20);
|
||||
* ```
|
||||
*/
|
||||
pixelate(image, options) {
|
||||
const parsed = PixelateOptionsSchema.parse(options);
|
||||
const { size, x = 0, y = 0, w = image.bitmap.width - x, h = image.bitmap.height - y, } = typeof parsed === "number"
|
||||
? { size: parsed }
|
||||
: parsed;
|
||||
const kernel = [
|
||||
[1 / 16, 2 / 16, 1 / 16],
|
||||
[2 / 16, 4 / 16, 2 / 16],
|
||||
[1 / 16, 2 / 16, 1 / 16],
|
||||
];
|
||||
const source = (0, utils_1.clone)(image);
|
||||
(0, utils_1.scan)(source, x, y, w, h, (xx, yx, idx) => {
|
||||
xx = size * Math.floor(xx / size);
|
||||
yx = size * Math.floor(yx / size);
|
||||
const value = applyKernel(source, kernel, xx, yx);
|
||||
image.bitmap.data[idx] = value[0];
|
||||
image.bitmap.data[idx + 1] = value[1];
|
||||
image.bitmap.data[idx + 2] = value[2];
|
||||
image.bitmap.data[idx + 3] = value[3];
|
||||
});
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Applies a convolution kernel to the image or a region
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* // apply a convolution kernel to the whole image
|
||||
* image.convolution([
|
||||
* [-1, -1, 0],
|
||||
* [-1, 1, 1],
|
||||
* [0, 1, 1],
|
||||
* ]);
|
||||
*
|
||||
* // apply a convolution kernel to a region
|
||||
* image.convolution([
|
||||
* [-1, -1, 0],
|
||||
* [-1, 1, 1],
|
||||
* [0, 1, 1],
|
||||
* ], 10, 10, 10, 20);
|
||||
* ```
|
||||
*/
|
||||
convolute(image, options) {
|
||||
const parsed = ConvoluteOptionsSchema.parse(options);
|
||||
const { kernel, x = 0, y = 0, w = image.bitmap.width - x, h = image.bitmap.height - y, } = "kernel" in parsed
|
||||
? parsed
|
||||
: { kernel: parsed };
|
||||
const source = (0, utils_1.clone)(image);
|
||||
(0, utils_1.scan)(source, x, y, w, h, (xx, yx, idx) => {
|
||||
const value = applyKernel(source, kernel, xx, yx);
|
||||
image.bitmap.data[idx] = (0, utils_1.limit255)(value[0]);
|
||||
image.bitmap.data[idx + 1] = (0, utils_1.limit255)(value[1]);
|
||||
image.bitmap.data[idx + 2] = (0, utils_1.limit255)(value[2]);
|
||||
image.bitmap.data[idx + 3] = (0, utils_1.limit255)(value[3]);
|
||||
});
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Apply multiple color modification rules
|
||||
* @param actions list of color modification rules, in following format: { apply: '<rule-name>', params: [ <rule-parameters> ] }
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.color([
|
||||
* { apply: "hue", params: [-90] },
|
||||
* { apply: "lighten", params: [50] },
|
||||
* { apply: "xor", params: ["#06D"] },
|
||||
* ]);
|
||||
* ```
|
||||
*/
|
||||
color(image, actions) {
|
||||
if (!actions || !Array.isArray(actions)) {
|
||||
throw new Error("actions must be an array");
|
||||
}
|
||||
actions.forEach((action) => ColorActionNameSchema.parse(action));
|
||||
actions = actions.map((action) => {
|
||||
if (action.apply === "xor" || action.apply === "mix") {
|
||||
action.params[0] = (0, tinycolor2_1.default)(action.params[0]).toRgb();
|
||||
}
|
||||
return action;
|
||||
});
|
||||
image.scan((_, __, idx) => {
|
||||
let clr = {
|
||||
r: image.bitmap.data[idx],
|
||||
g: image.bitmap.data[idx + 1],
|
||||
b: image.bitmap.data[idx + 2],
|
||||
};
|
||||
const colorModifier = (i, amount) => (0, utils_1.limit255)(clr[i] + amount);
|
||||
actions.forEach((action) => {
|
||||
if (action.apply === "mix") {
|
||||
clr = mix(clr, action.params[0], action.params[1]);
|
||||
}
|
||||
else if (action.apply === "tint") {
|
||||
clr = mix(clr, { r: 255, g: 255, b: 255 }, action.params?.[0]);
|
||||
}
|
||||
else if (action.apply === "shade") {
|
||||
clr = mix(clr, { r: 0, g: 0, b: 0 }, action.params?.[0]);
|
||||
}
|
||||
else if (action.apply === "xor") {
|
||||
clr = {
|
||||
r: clr.r ^ action.params[0].r,
|
||||
g: clr.g ^ action.params[0].g,
|
||||
b: clr.b ^ action.params[0].b,
|
||||
};
|
||||
}
|
||||
else if (action.apply === "red") {
|
||||
clr.r = colorModifier("r", action.params[0]);
|
||||
}
|
||||
else if (action.apply === "green") {
|
||||
clr.g = colorModifier("g", action.params[0]);
|
||||
}
|
||||
else if (action.apply === "blue") {
|
||||
clr.b = colorModifier("b", action.params[0]);
|
||||
}
|
||||
else {
|
||||
if (action.apply === "hue") {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
action.apply = "spin";
|
||||
}
|
||||
const tnyClr = (0, tinycolor2_1.default)(clr);
|
||||
const fn = tnyClr[action.apply].bind(tnyClr);
|
||||
if (!fn) {
|
||||
throw new Error("action " + action.apply + " not supported");
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
clr = fn(...(action.params || [])).toRgb();
|
||||
}
|
||||
});
|
||||
image.bitmap.data[idx] = clr.r;
|
||||
image.bitmap.data[idx + 1] = clr.g;
|
||||
image.bitmap.data[idx + 2] = clr.b;
|
||||
});
|
||||
return image;
|
||||
},
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,4DAAmC;AACnC,uCAAoD;AACpD,uCAAwD;AACxD,6BAAwB;AAExB,MAAM,uBAAuB,GAAG,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;AACnE,MAAM,+BAA+B,GAAG,OAAC,CAAC,MAAM,CAAC;IAC/C,2CAA2C;IAC3C,MAAM,EAAE,uBAAuB;IAC/B,sDAAsD;IACtD,YAAY,EAAE,OAAC,CAAC,UAAU,CAAC,YAAI,CAAC,CAAC,QAAQ,EAAE;CAC5C,CAAC,CAAC;AACH,MAAM,wBAAwB,GAAG,OAAC,CAAC,KAAK,CAAC;IACvC,uBAAuB;IACvB,+BAA+B;CAChC,CAAC,CAAC;AAIH,MAAM,6BAA6B,GAAG,OAAC,CAAC,MAAM,CAAC;IAC7C,6BAA6B;IAC7B,MAAM,EAAE,uBAAuB;IAC/B,2DAA2D;IAC3D,CAAC,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACxB,2DAA2D;IAC3D,CAAC,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACxB,sDAAsD;IACtD,CAAC,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACxB,uDAAuD;IACvD,CAAC,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACzB,CAAC,CAAC;AACH,MAAM,sBAAsB,GAAG,OAAC,CAAC,KAAK,CAAC;IACrC,uBAAuB;IACvB,6BAA6B;CAC9B,CAAC,CAAC;AAKH,MAAM,YAAY,GAAG,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACrD,MAAM,4BAA4B,GAAG,OAAC,CAAC,MAAM,CAAC;IAC5C,6BAA6B;IAC7B,IAAI,EAAE,YAAY;IAClB,+CAA+C;IAC/C,CAAC,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACxB,+CAA+C;IAC/C,CAAC,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACxB,0CAA0C;IAC1C,CAAC,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACxB,2CAA2C;IAC3C,CAAC,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACzB,CAAC,CAAC;AACH,MAAM,qBAAqB,GAAG,OAAC,CAAC,KAAK,CAAC;IACpC,YAAY;IACZ,4BAA4B;CAC7B,CAAC,CAAC;AAKH,SAAS,WAAW,CAClB,KAAgB,EAChB,MAAkB,EAClB,CAAS,EACT,CAAS;IAET,MAAM,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAqC,CAAC;IAC/D,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IAErC,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC;QAC7C,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,EAAE,CAAE,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC;YAClD,MAAM,GAAG,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;YAE9D,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAE,GAAG,MAAM,CAAC,EAAE,CAAE,CAAC,EAAE,CAAE,CAAC;YACvD,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAE,GAAG,MAAM,CAAC,EAAE,CAAE,CAAC,EAAE,CAAE,CAAC;YAC3D,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAE,GAAG,MAAM,CAAC,EAAE,CAAE,CAAC,EAAE,CAAE,CAAC;YAC3D,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAE,GAAG,MAAM,CAAC,EAAE,CAAE,CAAC,EAAE,CAAE,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,GAAG,CAAC,GAAa,EAAE,IAAc,EAAE,CAAC,GAAG,EAAE;IAChD,OAAO;QACL,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;QACvC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;QACvC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;KACxC,CAAC;AACJ,CAAC;AAED,MAAM,eAAe,GAAG,OAAC,CAAC,MAAM,CAAC;IAC/B,KAAK,EAAE,OAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IACvB,MAAM,EAAE,OAAC,CAAC,KAAK,CAAC,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;CACjD,CAAC,CAAC;AAGH,MAAM,gBAAgB,GAAG,OAAC,CAAC,MAAM,CAAC;IAChC,KAAK,EAAE,OAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IACxB,MAAM,EAAE,OAAC,CAAC,KAAK,CAAC,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;CACjD,CAAC,CAAC;AAGH,MAAM,mBAAmB,GAAG,OAAC,CAAC,MAAM,CAAC;IACnC,KAAK,EAAE,OAAC,CAAC,OAAO,CAAC,SAAS,CAAC;IAC3B,MAAM,EAAE,OAAC,CAAC,KAAK,CAAC,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CACzD,CAAC,CAAC;AAGH,MAAM,cAAc,GAAG,OAAC,CAAC,MAAM,CAAC;IAC9B,CAAC,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IAC7B,CAAC,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IAC7B,CAAC,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;CAC9B,CAAC,CAAC;AAEH,MAAM,eAAe,GAAG,OAAC,CAAC,MAAM,CAAC;IAC/B,KAAK,EAAE,OAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IACvB,MAAM,EAAE,OAAC,CAAC,KAAK,CAAC;QACd,OAAC,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,CAAC;QACzB,OAAC,CAAC,KAAK,CAAC,CAAC,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;KACtD,CAAC;CACH,CAAC,CAAC;AAGH,MAAM,gBAAgB,GAAG,OAAC,CAAC,MAAM,CAAC;IAChC,KAAK,EAAE,OAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IACxB,MAAM,EAAE,OAAC,CAAC,KAAK,CAAC,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CACzD,CAAC,CAAC;AAGH,MAAM,iBAAiB,GAAG,OAAC,CAAC,MAAM,CAAC;IACjC,KAAK,EAAE,OAAC,CAAC,OAAO,CAAC,OAAO,CAAC;IACzB,MAAM,EAAE,OAAC,CAAC,KAAK,CAAC,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CACzD,CAAC,CAAC;AAGH,MAAM,eAAe,GAAG,OAAC,CAAC,MAAM,CAAC;IAC/B,KAAK,EAAE,OAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IACvB,MAAM,EAAE,OAAC,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,CAAC;CAClC,CAAC,CAAC;AAGH,MAAM,eAAe,GAAG,OAAC,CAAC,MAAM,CAAC;IAC/B,KAAK,EAAE,OAAC,CAAC,OAAO,CAAC,KAAK,Line truncated
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "commonjs"
|
||||
}
|
||||
+706
@@ -0,0 +1,706 @@
|
||||
import { Edge, JimpClass } from "@jimp/types";
|
||||
import { z } from "zod";
|
||||
declare const ConvolutionOptionsSchema: z.ZodUnion<[z.ZodArray<z.ZodArray<z.ZodNumber, "many">, "many">, z.ZodObject<{
|
||||
/** a matrix to weight the neighbors sum */
|
||||
kernel: z.ZodArray<z.ZodArray<z.ZodNumber, "many">, "many">;
|
||||
/**define how to sum pixels from outside the border */
|
||||
edgeHandling: z.ZodOptional<z.ZodNativeEnum<typeof Edge>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
kernel: number[][];
|
||||
edgeHandling?: Edge | undefined;
|
||||
}, {
|
||||
kernel: number[][];
|
||||
edgeHandling?: Edge | undefined;
|
||||
}>]>;
|
||||
type ConvolutionOptions = z.infer<typeof ConvolutionOptionsSchema>;
|
||||
declare const ConvoluteOptionsSchema: z.ZodUnion<[z.ZodArray<z.ZodArray<z.ZodNumber, "many">, "many">, z.ZodObject<{
|
||||
/** the convolution kernel */
|
||||
kernel: z.ZodArray<z.ZodArray<z.ZodNumber, "many">, "many">;
|
||||
/** the x position of the region to apply convolution to */
|
||||
x: z.ZodOptional<z.ZodNumber>;
|
||||
/** the y position of the region to apply convolution to */
|
||||
y: z.ZodOptional<z.ZodNumber>;
|
||||
/** the width of the region to apply convolution to */
|
||||
w: z.ZodOptional<z.ZodNumber>;
|
||||
/** the height of the region to apply convolution to */
|
||||
h: z.ZodOptional<z.ZodNumber>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
kernel: number[][];
|
||||
x?: number | undefined;
|
||||
y?: number | undefined;
|
||||
w?: number | undefined;
|
||||
h?: number | undefined;
|
||||
}, {
|
||||
kernel: number[][];
|
||||
x?: number | undefined;
|
||||
y?: number | undefined;
|
||||
w?: number | undefined;
|
||||
h?: number | undefined;
|
||||
}>]>;
|
||||
type ConvoluteOptions = z.infer<typeof ConvoluteOptionsSchema>;
|
||||
declare const PixelateOptionsSchema: z.ZodUnion<[z.ZodNumber, z.ZodObject<{
|
||||
/** the size of the pixels */
|
||||
size: z.ZodNumber;
|
||||
/** the x position of the region to pixelate */
|
||||
x: z.ZodOptional<z.ZodNumber>;
|
||||
/** the y position of the region to pixelate */
|
||||
y: z.ZodOptional<z.ZodNumber>;
|
||||
/** the width of the region to pixelate */
|
||||
w: z.ZodOptional<z.ZodNumber>;
|
||||
/** the height of the region to pixelate */
|
||||
h: z.ZodOptional<z.ZodNumber>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
size: number;
|
||||
x?: number | undefined;
|
||||
y?: number | undefined;
|
||||
w?: number | undefined;
|
||||
h?: number | undefined;
|
||||
}, {
|
||||
size: number;
|
||||
x?: number | undefined;
|
||||
y?: number | undefined;
|
||||
w?: number | undefined;
|
||||
h?: number | undefined;
|
||||
}>]>;
|
||||
type PixelateOptions = z.infer<typeof PixelateOptionsSchema>;
|
||||
declare const HueActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"hue">;
|
||||
params: z.ZodTuple<[z.ZodNumber], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [number];
|
||||
apply: "hue";
|
||||
}, {
|
||||
params: [number];
|
||||
apply: "hue";
|
||||
}>;
|
||||
export type HueAction = z.infer<typeof HueActionSchema>;
|
||||
declare const SpinActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"spin">;
|
||||
params: z.ZodTuple<[z.ZodNumber], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [number];
|
||||
apply: "spin";
|
||||
}, {
|
||||
params: [number];
|
||||
apply: "spin";
|
||||
}>;
|
||||
export type SpinAction = z.infer<typeof SpinActionSchema>;
|
||||
declare const LightenActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"lighten">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "lighten";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "lighten";
|
||||
params?: [number] | undefined;
|
||||
}>;
|
||||
export type LightenAction = z.infer<typeof LightenActionSchema>;
|
||||
declare const MixActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"mix">;
|
||||
params: z.ZodUnion<[z.ZodTuple<[z.ZodObject<{
|
||||
r: z.ZodNumber;
|
||||
g: z.ZodNumber;
|
||||
b: z.ZodNumber;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}>], null>, z.ZodTuple<[z.ZodObject<{
|
||||
r: z.ZodNumber;
|
||||
g: z.ZodNumber;
|
||||
b: z.ZodNumber;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}>, z.ZodNumber], null>]>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}] | [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}, number];
|
||||
apply: "mix";
|
||||
}, {
|
||||
params: [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}] | [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}, number];
|
||||
apply: "mix";
|
||||
}>;
|
||||
export type MixAction = z.infer<typeof MixActionSchema>;
|
||||
declare const TintActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"tint">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "tint";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "tint";
|
||||
params?: [number] | undefined;
|
||||
}>;
|
||||
export type TintAction = z.infer<typeof TintActionSchema>;
|
||||
declare const ShadeActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"shade">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "shade";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "shade";
|
||||
params?: [number] | undefined;
|
||||
}>;
|
||||
export type ShadeAction = z.infer<typeof ShadeActionSchema>;
|
||||
declare const XorActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"xor">;
|
||||
params: z.ZodTuple<[z.ZodObject<{
|
||||
r: z.ZodNumber;
|
||||
g: z.ZodNumber;
|
||||
b: z.ZodNumber;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}>], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}];
|
||||
apply: "xor";
|
||||
}, {
|
||||
params: [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}];
|
||||
apply: "xor";
|
||||
}>;
|
||||
export type XorAction = z.infer<typeof XorActionSchema>;
|
||||
declare const RedActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"red">;
|
||||
params: z.ZodTuple<[z.ZodNumber], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [number];
|
||||
apply: "red";
|
||||
}, {
|
||||
params: [number];
|
||||
apply: "red";
|
||||
}>;
|
||||
export type RedAction = z.infer<typeof RedActionSchema>;
|
||||
declare const GreenActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"green">;
|
||||
params: z.ZodTuple<[z.ZodNumber], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [number];
|
||||
apply: "green";
|
||||
}, {
|
||||
params: [number];
|
||||
apply: "green";
|
||||
}>;
|
||||
export type GreenAction = z.infer<typeof GreenActionSchema>;
|
||||
declare const BlueActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"blue">;
|
||||
params: z.ZodTuple<[z.ZodNumber], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [number];
|
||||
apply: "blue";
|
||||
}, {
|
||||
params: [number];
|
||||
apply: "blue";
|
||||
}>;
|
||||
export type BlueAction = z.infer<typeof BlueActionSchema>;
|
||||
declare const BrightenActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"brighten">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "brighten";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "brighten";
|
||||
params?: [number] | undefined;
|
||||
}>;
|
||||
export type BrightenAction = z.infer<typeof BrightenActionSchema>;
|
||||
declare const DarkenActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"darken">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "darken";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "darken";
|
||||
params?: [number] | undefined;
|
||||
}>;
|
||||
export type DarkenAction = z.infer<typeof DarkenActionSchema>;
|
||||
declare const DesaturateActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"desaturate">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "desaturate";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "desaturate";
|
||||
params?: [number] | undefined;
|
||||
}>;
|
||||
export type DesaturateAction = z.infer<typeof DesaturateActionSchema>;
|
||||
declare const SaturateActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"saturate">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "saturate";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "saturate";
|
||||
params?: [number] | undefined;
|
||||
}>;
|
||||
export type SaturateAction = z.infer<typeof SaturateActionSchema>;
|
||||
declare const GrayscaleActionSchema: z.ZodObject<{
|
||||
apply: z.ZodLiteral<"greyscale">;
|
||||
params: z.ZodOptional<z.ZodTuple<[], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "greyscale";
|
||||
params?: [] | undefined;
|
||||
}, {
|
||||
apply: "greyscale";
|
||||
params?: [] | undefined;
|
||||
}>;
|
||||
export type GrayscaleAction = z.infer<typeof GrayscaleActionSchema>;
|
||||
declare const ColorActionNameSchema: z.ZodUnion<[z.ZodObject<{
|
||||
apply: z.ZodLiteral<"hue">;
|
||||
params: z.ZodTuple<[z.ZodNumber], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [number];
|
||||
apply: "hue";
|
||||
}, {
|
||||
params: [number];
|
||||
apply: "hue";
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"spin">;
|
||||
params: z.ZodTuple<[z.ZodNumber], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [number];
|
||||
apply: "spin";
|
||||
}, {
|
||||
params: [number];
|
||||
apply: "spin";
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"lighten">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "lighten";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "lighten";
|
||||
params?: [number] | undefined;
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"mix">;
|
||||
params: z.ZodUnion<[z.ZodTuple<[z.ZodObject<{
|
||||
r: z.ZodNumber;
|
||||
g: z.ZodNumber;
|
||||
b: z.ZodNumber;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}>], null>, z.ZodTuple<[z.ZodObject<{
|
||||
r: z.ZodNumber;
|
||||
g: z.ZodNumber;
|
||||
b: z.ZodNumber;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}>, z.ZodNumber], null>]>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}] | [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}, number];
|
||||
apply: "mix";
|
||||
}, {
|
||||
params: [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}] | [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}, number];
|
||||
apply: "mix";
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"tint">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "tint";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "tint";
|
||||
params?: [number] | undefined;
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"shade">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "shade";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "shade";
|
||||
params?: [number] | undefined;
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"xor">;
|
||||
params: z.ZodTuple<[z.ZodObject<{
|
||||
r: z.ZodNumber;
|
||||
g: z.ZodNumber;
|
||||
b: z.ZodNumber;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}, {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}>], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}];
|
||||
apply: "xor";
|
||||
}, {
|
||||
params: [{
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
}];
|
||||
apply: "xor";
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"red">;
|
||||
params: z.ZodTuple<[z.ZodNumber], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [number];
|
||||
apply: "red";
|
||||
}, {
|
||||
params: [number];
|
||||
apply: "red";
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"green">;
|
||||
params: z.ZodTuple<[z.ZodNumber], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [number];
|
||||
apply: "green";
|
||||
}, {
|
||||
params: [number];
|
||||
apply: "green";
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"blue">;
|
||||
params: z.ZodTuple<[z.ZodNumber], null>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
params: [number];
|
||||
apply: "blue";
|
||||
}, {
|
||||
params: [number];
|
||||
apply: "blue";
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"brighten">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "brighten";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "brighten";
|
||||
params?: [number] | undefined;
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"darken">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "darken";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "darken";
|
||||
params?: [number] | undefined;
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"desaturate">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "desaturate";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "desaturate";
|
||||
params?: [number] | undefined;
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"saturate">;
|
||||
params: z.ZodOptional<z.ZodTuple<[z.ZodNumber], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "saturate";
|
||||
params?: [number] | undefined;
|
||||
}, {
|
||||
apply: "saturate";
|
||||
params?: [number] | undefined;
|
||||
}>, z.ZodObject<{
|
||||
apply: z.ZodLiteral<"greyscale">;
|
||||
params: z.ZodOptional<z.ZodTuple<[], null>>;
|
||||
}, "strip", z.ZodTypeAny, {
|
||||
apply: "greyscale";
|
||||
params?: [] | undefined;
|
||||
}, {
|
||||
apply: "greyscale";
|
||||
params?: [] | undefined;
|
||||
}>]>;
|
||||
export type ColorAction = z.infer<typeof ColorActionNameSchema>;
|
||||
export declare const ColorActionName: Readonly<{
|
||||
LIGHTEN: "lighten";
|
||||
BRIGHTEN: "brighten";
|
||||
DARKEN: "darken";
|
||||
DESATURATE: "desaturate";
|
||||
SATURATE: "saturate";
|
||||
GREYSCALE: "greyscale";
|
||||
SPIN: "spin";
|
||||
HUE: "hue";
|
||||
MIX: "mix";
|
||||
TINT: "tint";
|
||||
SHADE: "shade";
|
||||
XOR: "xor";
|
||||
RED: "red";
|
||||
GREEN: "green";
|
||||
BLUE: "blue";
|
||||
}>;
|
||||
export declare const methods: {
|
||||
/**
|
||||
* Normalizes the image.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.normalize();
|
||||
* ```
|
||||
*/
|
||||
normalize<I extends JimpClass>(image: I): I;
|
||||
/**
|
||||
* Inverts the colors in the image.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.invert();
|
||||
* ```
|
||||
*/
|
||||
invert<I extends JimpClass>(image: I): I;
|
||||
/**
|
||||
* Adjusts the brightness of the image
|
||||
* @param val the amount to adjust the brightness.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.brightness(0.5);
|
||||
* ```
|
||||
*/
|
||||
brightness<I extends JimpClass>(image: I, val: number): I;
|
||||
/**
|
||||
* Adjusts the contrast of the image
|
||||
* @param val the amount to adjust the contrast, a number between -1 and +1
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.contrast(0.75);
|
||||
* ```
|
||||
*/
|
||||
contrast<I extends JimpClass>(image: I, val: number): I;
|
||||
/**
|
||||
* Apply a posterize effect
|
||||
* @param n the amount to adjust the contrast, minimum threshold is two
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.posterize(5);
|
||||
* ```
|
||||
*/
|
||||
posterize<I extends JimpClass>(image: I, n: number): I;
|
||||
/**
|
||||
* Removes colour from the image using ITU Rec 709 luminance values
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.greyscale();
|
||||
* ```
|
||||
*/
|
||||
greyscale<I extends JimpClass>(image: I): I;
|
||||
/**
|
||||
* Multiplies the opacity of each pixel by a factor between 0 and 1
|
||||
* @param f A number, the factor by which to multiply the opacity of each pixel
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.opacity(0.5);
|
||||
* ```
|
||||
*/
|
||||
opacity<I extends JimpClass>(image: I, f: number): I;
|
||||
/**
|
||||
* Applies a sepia tone to the image.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.sepia();
|
||||
* ```
|
||||
*/
|
||||
sepia<I extends JimpClass>(image: I): I;
|
||||
/**
|
||||
* Fades each pixel by a factor between 0 and 1
|
||||
* @param f A number from 0 to 1. 0 will haven no effect. 1 will turn the image completely transparent.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.fade(0.7);
|
||||
* ```
|
||||
*/
|
||||
fade<I extends JimpClass>(image: I, f: number): I;
|
||||
/**
|
||||
* Adds each element of the image to its local neighbors, weighted by the kernel
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.convolute([
|
||||
* [-1, -1, 0],
|
||||
* [-1, 1, 1],
|
||||
* [0, 1, 1],
|
||||
* ]);
|
||||
* ```
|
||||
*/
|
||||
convolution<I extends JimpClass>(image: I, options: ConvolutionOptions): I;
|
||||
/**
|
||||
* Set the alpha channel on every pixel to fully opaque.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.opaque();
|
||||
* ```
|
||||
*/
|
||||
opaque<I extends JimpClass>(image: I): I;
|
||||
/**
|
||||
* Pixelates the image or a region
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* // pixelate the whole image
|
||||
* image.pixelate(10);
|
||||
*
|
||||
* // pixelate a region
|
||||
* image.pixelate(10, 10, 10, 20, 20);
|
||||
* ```
|
||||
*/
|
||||
pixelate<I extends JimpClass>(image: I, options: PixelateOptions): I;
|
||||
/**
|
||||
* Applies a convolution kernel to the image or a region
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* // apply a convolution kernel to the whole image
|
||||
* image.convolution([
|
||||
* [-1, -1, 0],
|
||||
* [-1, 1, 1],
|
||||
* [0, 1, 1],
|
||||
* ]);
|
||||
*
|
||||
* // apply a convolution kernel to a region
|
||||
* image.convolution([
|
||||
* [-1, -1, 0],
|
||||
* [-1, 1, 1],
|
||||
* [0, 1, 1],
|
||||
* ], 10, 10, 10, 20);
|
||||
* ```
|
||||
*/
|
||||
convolute<I extends JimpClass>(image: I, options: ConvoluteOptions): I;
|
||||
/**
|
||||
* Apply multiple color modification rules
|
||||
* @param actions list of color modification rules, in following format: { apply: '<rule-name>', params: [ <rule-parameters> ] }
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.color([
|
||||
* { apply: "hue", params: [-90] },
|
||||
* { apply: "lighten", params: [50] },
|
||||
* { apply: "xor", params: ["#06D"] },
|
||||
* ]);
|
||||
* ```
|
||||
*/
|
||||
color<I extends JimpClass>(image: I, actions: ColorAction[]): I;
|
||||
};
|
||||
export {};
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
||||
+707
@@ -0,0 +1,707 @@
|
||||
import tinyColor from "tinycolor2";
|
||||
import { clone, limit255, scan } from "@jimp/utils";
|
||||
import { Edge } from "@jimp/types";
|
||||
import { z } from "zod";
|
||||
const ConvolutionMatrixSchema = z.array(z.number()).min(1).array();
|
||||
const ConvolutionComplexOptionsSchema = z.object({
|
||||
/** a matrix to weight the neighbors sum */
|
||||
kernel: ConvolutionMatrixSchema,
|
||||
/**define how to sum pixels from outside the border */
|
||||
edgeHandling: z.nativeEnum(Edge).optional(),
|
||||
});
|
||||
const ConvolutionOptionsSchema = z.union([
|
||||
ConvolutionMatrixSchema,
|
||||
ConvolutionComplexOptionsSchema,
|
||||
]);
|
||||
const ConvoluteComplexOptionsSchema = z.object({
|
||||
/** the convolution kernel */
|
||||
kernel: ConvolutionMatrixSchema,
|
||||
/** the x position of the region to apply convolution to */
|
||||
x: z.number().optional(),
|
||||
/** the y position of the region to apply convolution to */
|
||||
y: z.number().optional(),
|
||||
/** the width of the region to apply convolution to */
|
||||
w: z.number().optional(),
|
||||
/** the height of the region to apply convolution to */
|
||||
h: z.number().optional(),
|
||||
});
|
||||
const ConvoluteOptionsSchema = z.union([
|
||||
ConvolutionMatrixSchema,
|
||||
ConvoluteComplexOptionsSchema,
|
||||
]);
|
||||
const PixelateSize = z.number().min(1).max(Infinity);
|
||||
const PixelateComplexOptionsSchema = z.object({
|
||||
/** the size of the pixels */
|
||||
size: PixelateSize,
|
||||
/** the x position of the region to pixelate */
|
||||
x: z.number().optional(),
|
||||
/** the y position of the region to pixelate */
|
||||
y: z.number().optional(),
|
||||
/** the width of the region to pixelate */
|
||||
w: z.number().optional(),
|
||||
/** the height of the region to pixelate */
|
||||
h: z.number().optional(),
|
||||
});
|
||||
const PixelateOptionsSchema = z.union([
|
||||
PixelateSize,
|
||||
PixelateComplexOptionsSchema,
|
||||
]);
|
||||
function applyKernel(image, kernel, x, y) {
|
||||
const value = [0, 0, 0, 0];
|
||||
const size = (kernel.length - 1) / 2;
|
||||
for (let kx = 0; kx < kernel.length; kx += 1) {
|
||||
for (let ky = 0; ky < kernel[kx].length; ky += 1) {
|
||||
const idx = image.getPixelIndex(x + kx - size, y + ky - size);
|
||||
value[0] += image.bitmap.data[idx] * kernel[kx][ky];
|
||||
value[1] += image.bitmap.data[idx + 1] * kernel[kx][ky];
|
||||
value[2] += image.bitmap.data[idx + 2] * kernel[kx][ky];
|
||||
value[3] += image.bitmap.data[idx + 3] * kernel[kx][ky];
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
function mix(clr, clr2, p = 50) {
|
||||
return {
|
||||
r: (clr2.r - clr.r) * (p / 100) + clr.r,
|
||||
g: (clr2.g - clr.g) * (p / 100) + clr.g,
|
||||
b: (clr2.b - clr.b) * (p / 100) + clr.b,
|
||||
};
|
||||
}
|
||||
const HueActionSchema = z.object({
|
||||
apply: z.literal("hue"),
|
||||
params: z.tuple([z.number().min(-360).max(360)]),
|
||||
});
|
||||
const SpinActionSchema = z.object({
|
||||
apply: z.literal("spin"),
|
||||
params: z.tuple([z.number().min(-360).max(360)]),
|
||||
});
|
||||
const LightenActionSchema = z.object({
|
||||
apply: z.literal("lighten"),
|
||||
params: z.tuple([z.number().min(0).max(100)]).optional(),
|
||||
});
|
||||
const RGBColorSchema = z.object({
|
||||
r: z.number().min(0).max(255),
|
||||
g: z.number().min(0).max(255),
|
||||
b: z.number().min(0).max(255),
|
||||
});
|
||||
const MixActionSchema = z.object({
|
||||
apply: z.literal("mix"),
|
||||
params: z.union([
|
||||
z.tuple([RGBColorSchema]),
|
||||
z.tuple([RGBColorSchema, z.number().min(0).max(100)]),
|
||||
]),
|
||||
});
|
||||
const TintActionSchema = z.object({
|
||||
apply: z.literal("tint"),
|
||||
params: z.tuple([z.number().min(0).max(100)]).optional(),
|
||||
});
|
||||
const ShadeActionSchema = z.object({
|
||||
apply: z.literal("shade"),
|
||||
params: z.tuple([z.number().min(0).max(100)]).optional(),
|
||||
});
|
||||
const XorActionSchema = z.object({
|
||||
apply: z.literal("xor"),
|
||||
params: z.tuple([RGBColorSchema]),
|
||||
});
|
||||
const RedActionSchema = z.object({
|
||||
apply: z.literal("red"),
|
||||
params: z.tuple([z.number().min(-255).max(255)]),
|
||||
});
|
||||
const GreenActionSchema = z.object({
|
||||
apply: z.literal("green"),
|
||||
params: z.tuple([z.number().min(-255).max(255)]),
|
||||
});
|
||||
const BlueActionSchema = z.object({
|
||||
apply: z.literal("blue"),
|
||||
params: z.tuple([z.number().min(-255).max(255)]),
|
||||
});
|
||||
const BrightenActionSchema = z.object({
|
||||
apply: z.literal("brighten"),
|
||||
params: z.tuple([z.number().min(0).max(100)]).optional(),
|
||||
});
|
||||
const DarkenActionSchema = z.object({
|
||||
apply: z.literal("darken"),
|
||||
params: z.tuple([z.number().min(0).max(100)]).optional(),
|
||||
});
|
||||
const DesaturateActionSchema = z.object({
|
||||
apply: z.literal("desaturate"),
|
||||
params: z.tuple([z.number().min(0).max(100)]).optional(),
|
||||
});
|
||||
const SaturateActionSchema = z.object({
|
||||
apply: z.literal("saturate"),
|
||||
params: z.tuple([z.number().min(0).max(100)]).optional(),
|
||||
});
|
||||
const GrayscaleActionSchema = z.object({
|
||||
apply: z.literal("greyscale"),
|
||||
params: z.tuple([]).optional(),
|
||||
});
|
||||
const ColorActionNameSchema = z.union([
|
||||
HueActionSchema,
|
||||
SpinActionSchema,
|
||||
LightenActionSchema,
|
||||
MixActionSchema,
|
||||
TintActionSchema,
|
||||
ShadeActionSchema,
|
||||
XorActionSchema,
|
||||
RedActionSchema,
|
||||
GreenActionSchema,
|
||||
BlueActionSchema,
|
||||
BrightenActionSchema,
|
||||
DarkenActionSchema,
|
||||
DesaturateActionSchema,
|
||||
SaturateActionSchema,
|
||||
GrayscaleActionSchema,
|
||||
]);
|
||||
export const ColorActionName = Object.freeze({
|
||||
LIGHTEN: "lighten",
|
||||
BRIGHTEN: "brighten",
|
||||
DARKEN: "darken",
|
||||
DESATURATE: "desaturate",
|
||||
SATURATE: "saturate",
|
||||
GREYSCALE: "greyscale",
|
||||
SPIN: "spin",
|
||||
HUE: "hue",
|
||||
MIX: "mix",
|
||||
TINT: "tint",
|
||||
SHADE: "shade",
|
||||
XOR: "xor",
|
||||
RED: "red",
|
||||
GREEN: "green",
|
||||
BLUE: "blue",
|
||||
});
|
||||
/**
|
||||
* Get an image's histogram
|
||||
* @return An object with an array of color occurrence counts for each channel (r,g,b)
|
||||
*/
|
||||
function histogram(image) {
|
||||
const histogram = {
|
||||
r: new Array(256).fill(0),
|
||||
g: new Array(256).fill(0),
|
||||
b: new Array(256).fill(0),
|
||||
};
|
||||
image.scan((_, __, index) => {
|
||||
histogram.r[image.bitmap.data[index + 0]]++;
|
||||
histogram.g[image.bitmap.data[index + 1]]++;
|
||||
histogram.b[image.bitmap.data[index + 2]]++;
|
||||
});
|
||||
return histogram;
|
||||
}
|
||||
/**
|
||||
* Normalize values
|
||||
* @param value Pixel channel value.
|
||||
* @param min Minimum value for channel
|
||||
* @param max Maximum value for channel
|
||||
*/
|
||||
const normalizeValue = function (value, min, max) {
|
||||
return ((value - min) * 255) / (max - min);
|
||||
};
|
||||
const getBounds = function (histogramChannel) {
|
||||
return [
|
||||
histogramChannel.findIndex((value) => value > 0),
|
||||
255 -
|
||||
histogramChannel
|
||||
.slice()
|
||||
.reverse()
|
||||
.findIndex((value) => value > 0),
|
||||
];
|
||||
};
|
||||
export const methods = {
|
||||
/**
|
||||
* Normalizes the image.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.normalize();
|
||||
* ```
|
||||
*/
|
||||
normalize(image) {
|
||||
const h = histogram(image);
|
||||
// store bounds (minimum and maximum values)
|
||||
const bounds = {
|
||||
r: getBounds(h.r),
|
||||
g: getBounds(h.g),
|
||||
b: getBounds(h.b),
|
||||
};
|
||||
// apply value transformations
|
||||
image.scan((_, __, idx) => {
|
||||
const r = image.bitmap.data[idx + 0];
|
||||
const g = image.bitmap.data[idx + 1];
|
||||
const b = image.bitmap.data[idx + 2];
|
||||
image.bitmap.data[idx + 0] = normalizeValue(r, bounds.r[0], bounds.r[1]);
|
||||
image.bitmap.data[idx + 1] = normalizeValue(g, bounds.g[0], bounds.g[1]);
|
||||
image.bitmap.data[idx + 2] = normalizeValue(b, bounds.b[0], bounds.b[1]);
|
||||
});
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Inverts the colors in the image.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.invert();
|
||||
* ```
|
||||
*/
|
||||
invert(image) {
|
||||
image.scan((_, __, idx) => {
|
||||
image.bitmap.data[idx] = 255 - image.bitmap.data[idx];
|
||||
image.bitmap.data[idx + 1] = 255 - image.bitmap.data[idx + 1];
|
||||
image.bitmap.data[idx + 2] = 255 - image.bitmap.data[idx + 2];
|
||||
});
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Adjusts the brightness of the image
|
||||
* @param val the amount to adjust the brightness.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.brightness(0.5);
|
||||
* ```
|
||||
*/
|
||||
brightness(image, val) {
|
||||
if (typeof val !== "number") {
|
||||
throw new Error("val must be numbers");
|
||||
}
|
||||
image.scan((_, __, idx) => {
|
||||
image.bitmap.data[idx] = limit255(image.bitmap.data[idx] * val);
|
||||
image.bitmap.data[idx + 1] = limit255(image.bitmap.data[idx + 1] * val);
|
||||
image.bitmap.data[idx + 2] = limit255(image.bitmap.data[idx + 2] * val);
|
||||
});
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Adjusts the contrast of the image
|
||||
* @param val the amount to adjust the contrast, a number between -1 and +1
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.contrast(0.75);
|
||||
* ```
|
||||
*/
|
||||
contrast(image, val) {
|
||||
if (typeof val !== "number") {
|
||||
throw new Error("val must be numbers");
|
||||
}
|
||||
if (val < -1 || val > +1) {
|
||||
throw new Error("val must be a number between -1 and +1");
|
||||
}
|
||||
const factor = (val + 1) / (1 - val);
|
||||
function adjust(value) {
|
||||
value = Math.floor(factor * (value - 127) + 127);
|
||||
return value < 0 ? 0 : value > 255 ? 255 : value;
|
||||
}
|
||||
image.scan((_, __, idx) => {
|
||||
image.bitmap.data[idx] = adjust(image.bitmap.data[idx]);
|
||||
image.bitmap.data[idx + 1] = adjust(image.bitmap.data[idx + 1]);
|
||||
image.bitmap.data[idx + 2] = adjust(image.bitmap.data[idx + 2]);
|
||||
});
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Apply a posterize effect
|
||||
* @param n the amount to adjust the contrast, minimum threshold is two
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.posterize(5);
|
||||
* ```
|
||||
*/
|
||||
posterize(image, n) {
|
||||
if (typeof n !== "number") {
|
||||
throw new Error("n must be numbers");
|
||||
}
|
||||
// minimum of 2 levels
|
||||
if (n < 2) {
|
||||
n = 2;
|
||||
}
|
||||
image.scan((_, __, idx) => {
|
||||
const r = image.bitmap.data[idx];
|
||||
const g = image.bitmap.data[idx + 1];
|
||||
const b = image.bitmap.data[idx + 2];
|
||||
image.bitmap.data[idx] =
|
||||
(Math.floor((r / 255) * (n - 1)) / (n - 1)) * 255;
|
||||
image.bitmap.data[idx + 1] =
|
||||
(Math.floor((g / 255) * (n - 1)) / (n - 1)) * 255;
|
||||
image.bitmap.data[idx + 2] =
|
||||
(Math.floor((b / 255) * (n - 1)) / (n - 1)) * 255;
|
||||
});
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Removes colour from the image using ITU Rec 709 luminance values
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.greyscale();
|
||||
* ```
|
||||
*/
|
||||
greyscale(image) {
|
||||
image.scan((_, __, idx) => {
|
||||
// const grey = parseInt(
|
||||
// 0.2126 * image.bitmap.data[idx]! +
|
||||
// 0.7152 * image.bitmap.data[idx + 1]! +
|
||||
// 0.0722 * image.bitmap.data[idx + 2]!,
|
||||
// 10
|
||||
// );
|
||||
const grey = 0.2126 * image.bitmap.data[idx] +
|
||||
0.7152 * image.bitmap.data[idx + 1] +
|
||||
0.0722 * image.bitmap.data[idx + 2];
|
||||
image.bitmap.data[idx] = grey;
|
||||
image.bitmap.data[idx + 1] = grey;
|
||||
image.bitmap.data[idx + 2] = grey;
|
||||
});
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Multiplies the opacity of each pixel by a factor between 0 and 1
|
||||
* @param f A number, the factor by which to multiply the opacity of each pixel
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.opacity(0.5);
|
||||
* ```
|
||||
*/
|
||||
opacity(image, f) {
|
||||
if (typeof f !== "number") {
|
||||
throw new Error("f must be a number");
|
||||
}
|
||||
if (f < 0 || f > 1) {
|
||||
throw new Error("f must be a number from 0 to 1");
|
||||
}
|
||||
image.scan((_, __, idx) => {
|
||||
const v = image.bitmap.data[idx + 3] * f;
|
||||
image.bitmap.data[idx + 3] = v;
|
||||
});
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Applies a sepia tone to the image.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.sepia();
|
||||
* ```
|
||||
*/
|
||||
sepia(image) {
|
||||
image.scan((_, __, idx) => {
|
||||
let red = image.bitmap.data[idx];
|
||||
let green = image.bitmap.data[idx + 1];
|
||||
let blue = image.bitmap.data[idx + 2];
|
||||
red = red * 0.393 + green * 0.769 + blue * 0.189;
|
||||
green = red * 0.349 + green * 0.686 + blue * 0.168;
|
||||
blue = red * 0.272 + green * 0.534 + blue * 0.131;
|
||||
image.bitmap.data[idx] = red < 255 ? red : 255;
|
||||
image.bitmap.data[idx + 1] = green < 255 ? green : 255;
|
||||
image.bitmap.data[idx + 2] = blue < 255 ? blue : 255;
|
||||
});
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Fades each pixel by a factor between 0 and 1
|
||||
* @param f A number from 0 to 1. 0 will haven no effect. 1 will turn the image completely transparent.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.fade(0.7);
|
||||
* ```
|
||||
*/
|
||||
fade(image, f) {
|
||||
if (typeof f !== "number") {
|
||||
throw new Error("f must be a number");
|
||||
}
|
||||
if (f < 0 || f > 1) {
|
||||
throw new Error("f must be a number from 0 to 1");
|
||||
}
|
||||
// this method is an alternative to opacity (which may be deprecated)
|
||||
return this.opacity(image, 1 - f);
|
||||
},
|
||||
/**
|
||||
* Adds each element of the image to its local neighbors, weighted by the kernel
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.convolute([
|
||||
* [-1, -1, 0],
|
||||
* [-1, 1, 1],
|
||||
* [0, 1, 1],
|
||||
* ]);
|
||||
* ```
|
||||
*/
|
||||
convolution(image, options) {
|
||||
const parsed = ConvolutionOptionsSchema.parse(options);
|
||||
const { kernel, edgeHandling = Edge.EXTEND } = "kernel" in parsed ? parsed : { kernel: parsed, edgeHandling: undefined };
|
||||
if (!kernel[0]) {
|
||||
throw new Error("kernel must be a matrix");
|
||||
}
|
||||
const newData = Buffer.from(image.bitmap.data);
|
||||
const kRows = kernel.length;
|
||||
const kCols = kernel[0].length;
|
||||
const rowEnd = Math.floor(kRows / 2);
|
||||
const colEnd = Math.floor(kCols / 2);
|
||||
const rowIni = -rowEnd;
|
||||
const colIni = -colEnd;
|
||||
let weight;
|
||||
let rSum;
|
||||
let gSum;
|
||||
let bSum;
|
||||
let ri;
|
||||
let gi;
|
||||
let bi;
|
||||
let xi;
|
||||
let yi;
|
||||
let idxi;
|
||||
image.scan((x, y, idx) => {
|
||||
bSum = 0;
|
||||
gSum = 0;
|
||||
rSum = 0;
|
||||
for (let row = rowIni; row <= rowEnd; row++) {
|
||||
for (let col = colIni; col <= colEnd; col++) {
|
||||
xi = x + col;
|
||||
yi = y + row;
|
||||
weight = kernel[row + rowEnd][col + colEnd];
|
||||
idxi = image.getPixelIndex(xi, yi, edgeHandling);
|
||||
if (idxi === -1) {
|
||||
bi = 0;
|
||||
gi = 0;
|
||||
ri = 0;
|
||||
}
|
||||
else {
|
||||
ri = image.bitmap.data[idxi + 0];
|
||||
gi = image.bitmap.data[idxi + 1];
|
||||
bi = image.bitmap.data[idxi + 2];
|
||||
}
|
||||
rSum += weight * ri;
|
||||
gSum += weight * gi;
|
||||
bSum += weight * bi;
|
||||
}
|
||||
}
|
||||
if (rSum < 0) {
|
||||
rSum = 0;
|
||||
}
|
||||
if (gSum < 0) {
|
||||
gSum = 0;
|
||||
}
|
||||
if (bSum < 0) {
|
||||
bSum = 0;
|
||||
}
|
||||
if (rSum > 255) {
|
||||
rSum = 255;
|
||||
}
|
||||
if (gSum > 255) {
|
||||
gSum = 255;
|
||||
}
|
||||
if (bSum > 255) {
|
||||
bSum = 255;
|
||||
}
|
||||
newData[idx + 0] = rSum;
|
||||
newData[idx + 1] = gSum;
|
||||
newData[idx + 2] = bSum;
|
||||
});
|
||||
image.bitmap.data = newData;
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Set the alpha channel on every pixel to fully opaque.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.opaque();
|
||||
* ```
|
||||
*/
|
||||
opaque(image) {
|
||||
image.scan((_, __, idx) => {
|
||||
image.bitmap.data[idx + 3] = 255;
|
||||
});
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Pixelates the image or a region
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* // pixelate the whole image
|
||||
* image.pixelate(10);
|
||||
*
|
||||
* // pixelate a region
|
||||
* image.pixelate(10, 10, 10, 20, 20);
|
||||
* ```
|
||||
*/
|
||||
pixelate(image, options) {
|
||||
const parsed = PixelateOptionsSchema.parse(options);
|
||||
const { size, x = 0, y = 0, w = image.bitmap.width - x, h = image.bitmap.height - y, } = typeof parsed === "number"
|
||||
? { size: parsed }
|
||||
: parsed;
|
||||
const kernel = [
|
||||
[1 / 16, 2 / 16, 1 / 16],
|
||||
[2 / 16, 4 / 16, 2 / 16],
|
||||
[1 / 16, 2 / 16, 1 / 16],
|
||||
];
|
||||
const source = clone(image);
|
||||
scan(source, x, y, w, h, (xx, yx, idx) => {
|
||||
xx = size * Math.floor(xx / size);
|
||||
yx = size * Math.floor(yx / size);
|
||||
const value = applyKernel(source, kernel, xx, yx);
|
||||
image.bitmap.data[idx] = value[0];
|
||||
image.bitmap.data[idx + 1] = value[1];
|
||||
image.bitmap.data[idx + 2] = value[2];
|
||||
image.bitmap.data[idx + 3] = value[3];
|
||||
});
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Applies a convolution kernel to the image or a region
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* // apply a convolution kernel to the whole image
|
||||
* image.convolution([
|
||||
* [-1, -1, 0],
|
||||
* [-1, 1, 1],
|
||||
* [0, 1, 1],
|
||||
* ]);
|
||||
*
|
||||
* // apply a convolution kernel to a region
|
||||
* image.convolution([
|
||||
* [-1, -1, 0],
|
||||
* [-1, 1, 1],
|
||||
* [0, 1, 1],
|
||||
* ], 10, 10, 10, 20);
|
||||
* ```
|
||||
*/
|
||||
convolute(image, options) {
|
||||
const parsed = ConvoluteOptionsSchema.parse(options);
|
||||
const { kernel, x = 0, y = 0, w = image.bitmap.width - x, h = image.bitmap.height - y, } = "kernel" in parsed
|
||||
? parsed
|
||||
: { kernel: parsed };
|
||||
const source = clone(image);
|
||||
scan(source, x, y, w, h, (xx, yx, idx) => {
|
||||
const value = applyKernel(source, kernel, xx, yx);
|
||||
image.bitmap.data[idx] = limit255(value[0]);
|
||||
image.bitmap.data[idx + 1] = limit255(value[1]);
|
||||
image.bitmap.data[idx + 2] = limit255(value[2]);
|
||||
image.bitmap.data[idx + 3] = limit255(value[3]);
|
||||
});
|
||||
return image;
|
||||
},
|
||||
/**
|
||||
* Apply multiple color modification rules
|
||||
* @param actions list of color modification rules, in following format: { apply: '<rule-name>', params: [ <rule-parameters> ] }
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.color([
|
||||
* { apply: "hue", params: [-90] },
|
||||
* { apply: "lighten", params: [50] },
|
||||
* { apply: "xor", params: ["#06D"] },
|
||||
* ]);
|
||||
* ```
|
||||
*/
|
||||
color(image, actions) {
|
||||
if (!actions || !Array.isArray(actions)) {
|
||||
throw new Error("actions must be an array");
|
||||
}
|
||||
actions.forEach((action) => ColorActionNameSchema.parse(action));
|
||||
actions = actions.map((action) => {
|
||||
if (action.apply === "xor" || action.apply === "mix") {
|
||||
action.params[0] = tinyColor(action.params[0]).toRgb();
|
||||
}
|
||||
return action;
|
||||
});
|
||||
image.scan((_, __, idx) => {
|
||||
let clr = {
|
||||
r: image.bitmap.data[idx],
|
||||
g: image.bitmap.data[idx + 1],
|
||||
b: image.bitmap.data[idx + 2],
|
||||
};
|
||||
const colorModifier = (i, amount) => limit255(clr[i] + amount);
|
||||
actions.forEach((action) => {
|
||||
if (action.apply === "mix") {
|
||||
clr = mix(clr, action.params[0], action.params[1]);
|
||||
}
|
||||
else if (action.apply === "tint") {
|
||||
clr = mix(clr, { r: 255, g: 255, b: 255 }, action.params?.[0]);
|
||||
}
|
||||
else if (action.apply === "shade") {
|
||||
clr = mix(clr, { r: 0, g: 0, b: 0 }, action.params?.[0]);
|
||||
}
|
||||
else if (action.apply === "xor") {
|
||||
clr = {
|
||||
r: clr.r ^ action.params[0].r,
|
||||
g: clr.g ^ action.params[0].g,
|
||||
b: clr.b ^ action.params[0].b,
|
||||
};
|
||||
}
|
||||
else if (action.apply === "red") {
|
||||
clr.r = colorModifier("r", action.params[0]);
|
||||
}
|
||||
else if (action.apply === "green") {
|
||||
clr.g = colorModifier("g", action.params[0]);
|
||||
}
|
||||
else if (action.apply === "blue") {
|
||||
clr.b = colorModifier("b", action.params[0]);
|
||||
}
|
||||
else {
|
||||
if (action.apply === "hue") {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
action.apply = "spin";
|
||||
}
|
||||
const tnyClr = tinyColor(clr);
|
||||
const fn = tnyClr[action.apply].bind(tnyClr);
|
||||
if (!fn) {
|
||||
throw new Error("action " + action.apply + " not supported");
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
clr = fn(...(action.params || [])).toRgb();
|
||||
}
|
||||
});
|
||||
image.bitmap.data[idx] = clr.r;
|
||||
image.bitmap.data[idx + 1] = clr.g;
|
||||
image.bitmap.data[idx + 2] = clr.b;
|
||||
});
|
||||
return image;
|
||||
},
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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 truncated
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import shared from "@jimp/config-eslint/base.js";
|
||||
export default [...shared];
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"name": "@jimp/plugin-color",
|
||||
"version": "1.6.0",
|
||||
"repository": "jimp-dev/jimp",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"test": "vitest",
|
||||
"test:browser": "vitest --config vitest.config.browser.mjs",
|
||||
"build": "tshy",
|
||||
"dev": "tshy --watch",
|
||||
"clean": "rm -rf node_modules .tshy .tshy-build dist .turbo"
|
||||
},
|
||||
"author": "Andrew Lisowski <lisowski54@gmail.com>",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@jimp/config-eslint": "1.6.0",
|
||||
"@jimp/config-typescript": "1.6.0",
|
||||
"@jimp/config-vitest": "1.6.0",
|
||||
"@jimp/js-jpeg": "1.6.0",
|
||||
"@jimp/js-png": "1.6.0",
|
||||
"@jimp/test-utils": "1.6.0",
|
||||
"@types/node": "^18.19.48",
|
||||
"@types/tinycolor2": "^1.4.6",
|
||||
"@vitest/browser": "^2.0.5",
|
||||
"eslint": "^9.9.1",
|
||||
"tshy": "^3.0.2",
|
||||
"typescript": "^5.5.4",
|
||||
"vite-plugin-node-polyfills": "^0.22.0",
|
||||
"vitest": "^2.0.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@jimp/core": "1.6.0",
|
||||
"@jimp/types": "1.6.0",
|
||||
"@jimp/utils": "1.6.0",
|
||||
"tinycolor2": "^1.6.0",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
"tshy": {
|
||||
"exclude": [
|
||||
"**/*.test.ts"
|
||||
],
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": "./src/index.ts"
|
||||
}
|
||||
},
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./dist/esm/index.d.ts",
|
||||
"default": "./dist/esm/index.js"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/commonjs/index.d.ts",
|
||||
"default": "./dist/commonjs/index.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"main": "./dist/commonjs/index.js",
|
||||
"types": "./dist/commonjs/index.d.ts",
|
||||
"type": "module",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"module": "./dist/esm/index.js",
|
||||
"gitHead": "c88abe6046dccbdb6e4f5f00c3dd403c81d83515"
|
||||
}
|
||||
Generated
Vendored
BIN
Binary file not shown.
|
After Width: | Height: | Size: 6.4 KiB |
Generated
Vendored
BIN
Binary file not shown.
|
After Width: | Height: | Size: 7.7 KiB |
Generated
Vendored
BIN
Binary file not shown.
|
After Width: | Height: | Size: 151 KiB |
+145
@@ -0,0 +1,145 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`Convolution > 3x3 sharp matrix on EDGE_CROP 1`] = `
|
||||
Visualization:
|
||||
|
||||
86666662
|
||||
68EEE82■
|
||||
6E□□□8■■
|
||||
6E□88■■■
|
||||
6E□88■■■
|
||||
688■■■■■
|
||||
62■■■■■■
|
||||
2■■■■■■■
|
||||
|
||||
Data:
|
||||
|
||||
88-88-88ᶠᶠ 66-66-66ᶠᶠ 66-66-66ᶠᶠ 66-66-66ᶠᶠ 66-66-66ᶠᶠ 66-66-66ᶠᶠ 66-66-66ᶠᶠ 22-22-22ᶠᶠ
|
||||
66-66-66ᶠᶠ 88-88-88ᶠᶠ EE-EE-EEᶠᶠ EE-EE-EEᶠᶠ EE-EE-EEᶠᶠ 88-88-88ᶠᶠ 22-22-22ᶠᶠ 00-00-00ᶠᶠ
|
||||
66-66-66ᶠᶠ EE-EE-EEᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ 88-88-88ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ
|
||||
66-66-66ᶠᶠ EE-EE-EEᶠᶠ FF-FF-FFᶠᶠ 88-88-88ᶠᶠ 88-88-88ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ
|
||||
66-66-66ᶠᶠ EE-EE-EEᶠᶠ FF-FF-FFᶠᶠ 88-88-88ᶠᶠ 88-88-88ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ
|
||||
66-66-66ᶠᶠ 88-88-88ᶠᶠ 88-88-88ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ
|
||||
66-66-66ᶠᶠ 22-22-22ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ
|
||||
22-22-22ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Convolution > 3x3 sharp matrix on EDGE_CROP 2`] = `
|
||||
Visualization:
|
||||
|
||||
□C■66662
|
||||
C■■2222■
|
||||
■■■2222■
|
||||
6222222■
|
||||
6222222■
|
||||
6222222■
|
||||
6222222■
|
||||
2■■■■■■■
|
||||
|
||||
Data:
|
||||
|
||||
FF-FF-FFᶠᶠ CC-CC-CCᶠᶠ 00-00-00ᶠᶠ 66-66-66ᶠᶠ 66-66-66ᶠᶠ 66-66-66ᶠᶠ 66-66-66ᶠᶠ 22-22-22ᶠᶠ
|
||||
CC-CC-CCᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 00-00-00ᶠᶠ
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 00-00-00ᶠᶠ
|
||||
66-66-66ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 00-00-00ᶠᶠ
|
||||
66-66-66ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 00-00-00ᶠᶠ
|
||||
66-66-66ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 00-00-00ᶠᶠ
|
||||
66-66-66ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 00-00-00ᶠᶠ
|
||||
22-22-22ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Convolution > 3x3 sharp matrix on EDGE_EXTEND 1`] = `
|
||||
Visualization:
|
||||
|
||||
22222222
|
||||
28EEE822
|
||||
2E□□□8■2
|
||||
2E□88■■2
|
||||
2E□88■■2
|
||||
288■■■■2
|
||||
22■■■■■2
|
||||
22222222
|
||||
|
||||
Data:
|
||||
|
||||
22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ
|
||||
22-22-22ᶠᶠ 88-88-88ᶠᶠ EE-EE-EEᶠᶠ EE-EE-EEᶠᶠ EE-EE-EEᶠᶠ 88-88-88ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ
|
||||
22-22-22ᶠᶠ EE-EE-EEᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ 88-88-88ᶠᶠ 00-00-00ᶠᶠ 22-22-22ᶠᶠ
|
||||
22-22-22ᶠᶠ EE-EE-EEᶠᶠ FF-FF-FFᶠᶠ 88-88-88ᶠᶠ 88-88-88ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 22-22-22ᶠᶠ
|
||||
22-22-22ᶠᶠ EE-EE-EEᶠᶠ FF-FF-FFᶠᶠ 88-88-88ᶠᶠ 88-88-88ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 22-22-22ᶠᶠ
|
||||
22-22-22ᶠᶠ 88-88-88ᶠᶠ 88-88-88ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 22-22-22ᶠᶠ
|
||||
22-22-22ᶠᶠ 22-22-22ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 22-22-22ᶠᶠ
|
||||
22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Convolution > 3x3 sharp matrix on EDGE_EXTEND 2`] = `
|
||||
Visualization:
|
||||
|
||||
8■■22222
|
||||
■■■22222
|
||||
■■■22222
|
||||
22222222
|
||||
22222222
|
||||
22222222
|
||||
22222222
|
||||
22222222
|
||||
|
||||
Data:
|
||||
|
||||
88-88-88ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ
|
||||
22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ
|
||||
22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ
|
||||
22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ
|
||||
22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ
|
||||
22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Convolution > 3x3 sharp matrix on EDGE_WRAP 1`] = `
|
||||
Visualization:
|
||||
|
||||
22222222
|
||||
28EEE822
|
||||
2E□□□8■2
|
||||
2E□88■■2
|
||||
2E□88■■2
|
||||
288■■■■2
|
||||
22■■■■■2
|
||||
22222222
|
||||
|
||||
Data:
|
||||
|
||||
22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ
|
||||
22-22-22ᶠᶠ 88-88-88ᶠᶠ EE-EE-EEᶠᶠ EE-EE-EEᶠᶠ EE-EE-EEᶠᶠ 88-88-88ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ
|
||||
22-22-22ᶠᶠ EE-EE-EEᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ FF-FF-FFᶠᶠ 88-88-88ᶠᶠ 00-00-00ᶠᶠ 22-22-22ᶠᶠ
|
||||
22-22-22ᶠᶠ EE-EE-EEᶠᶠ FF-FF-FFᶠᶠ 88-88-88ᶠᶠ 88-88-88ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 22-22-22ᶠᶠ
|
||||
22-22-22ᶠᶠ EE-EE-EEᶠᶠ FF-FF-FFᶠᶠ 88-88-88ᶠᶠ 88-88-88ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 22-22-22ᶠᶠ
|
||||
22-22-22ᶠᶠ 88-88-88ᶠᶠ 88-88-88ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 22-22-22ᶠᶠ
|
||||
22-22-22ᶠᶠ 22-22-22ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 22-22-22ᶠᶠ
|
||||
22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Convolution > 3x3 sharp matrix on EDGE_WRAP 2`] = `
|
||||
Visualization:
|
||||
|
||||
□8■2222E
|
||||
8■■22228
|
||||
■■■22222
|
||||
22222222
|
||||
22222222
|
||||
22222222
|
||||
22222222
|
||||
E8222228
|
||||
|
||||
Data:
|
||||
|
||||
FF-FF-FFᶠᶠ 88-88-88ᶠᶠ 00-00-00ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ EE-EE-EEᶠᶠ
|
||||
88-88-88ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 88-88-88ᶠᶠ
|
||||
00-00-00ᶠᶠ 00-00-00ᶠᶠ 00-00-00ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ
|
||||
22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ
|
||||
22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ
|
||||
22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ
|
||||
22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ
|
||||
EE-EE-EEᶠᶠ 88-88-88ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 22-22-22ᶠᶠ 88-88-88ᶠᶠ
|
||||
`;
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`brightness > should be able to brighten 1`] = `
|
||||
Visualization:
|
||||
|
||||
6666666666
|
||||
6666666666
|
||||
6666666666
|
||||
6666666666
|
||||
6666666666
|
||||
6666666666
|
||||
6666666666
|
||||
6666666666
|
||||
6666666666
|
||||
6666666666
|
||||
|
||||
Data:
|
||||
|
||||
FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸
|
||||
FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸
|
||||
FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸
|
||||
FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸
|
||||
FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸
|
||||
FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸
|
||||
FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸
|
||||
FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸
|
||||
FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸
|
||||
FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸ FF-00-00⁸⁸
|
||||
`;
|
||||
|
||||
exports[`brightness > should be able to darken 1`] = `
|
||||
Visualization:
|
||||
|
||||
CCCCCCCCCC
|
||||
CCCCCCCCCC
|
||||
CCCCCCCCCC
|
||||
CCCCCCCCCC
|
||||
CCCCCCCCCC
|
||||
CCCCCCCCCC
|
||||
CCCCCCCCCC
|
||||
CCCCCCCCCC
|
||||
CCCCCCCCCC
|
||||
CCCCCCCCCC
|
||||
|
||||
Data:
|
||||
|
||||
22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸
|
||||
22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸
|
||||
22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸
|
||||
22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸
|
||||
22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸
|
||||
22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸
|
||||
22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸
|
||||
22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸
|
||||
22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸
|
||||
22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸ 22-00-00⁸⁸
|
||||
`;
|
||||
|
||||
exports[`canvas color transformation > brighten 1`] = `
|
||||
Visualization:
|
||||
|
||||
7777777777
|
||||
777▫FF▫777
|
||||
77FFFFFF77
|
||||
7▫FF▫▫FF▫7
|
||||
7FF▫77▫FF7
|
||||
7FF▫77▫FF7
|
||||
7▫FF▫▫FF▫7
|
||||
77FFFFFF77
|
||||
777▫FF▫777
|
||||
7777777777
|
||||
|
||||
Data:
|
||||
|
||||
40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ FF-40-40⁸⁸ FF-40-40ᶠᶠ FF-40-40ᶠᶠ FF-40-40⁸⁸ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ 40-40-40⁰⁰ FF-40-40ᶠᶠ FF-40-40ᶠᶠ FF-40-40ᶠᶠ FF-40-40ᶠᶠ FF-40-40ᶠᶠ FF-40-40ᶠᶠ 40-40-40⁰⁰ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ FF-40-40⁸⁸ FF-40-40ᶠᶠ FF-40-40ᶠᶠ FF-40-40⁸⁸ FF-40-40⁸⁸ FF-40-40ᶠᶠ FF-40-40ᶠᶠ FF-40-40⁸⁸ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ FF-40-40ᶠᶠ FF-40-40ᶠᶠ FF-40-40⁸⁸ 40-40-40⁰⁰ 40-40-40⁰⁰ FF-40-40⁸⁸ FF-40-40ᶠᶠ FF-40-40ᶠᶠ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ FF-40-40ᶠᶠ FF-40-40ᶠᶠ FF-40-40⁸⁸ 40-40-40⁰⁰ 40-40-40⁰⁰ FF-40-40⁸⁸ FF-40-40ᶠᶠ FF-40-40ᶠᶠ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ FF-40-40⁸⁸ FF-40-40ᶠᶠ FF-40-40ᶠᶠ FF-40-40⁸⁸ FF-40-40⁸⁸ FF-40-40ᶠᶠ FF-40-40ᶠᶠ FF-40-40⁸⁸ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ 40-40-40⁰⁰ FF-40-40ᶠᶠ FF-40-40ᶠᶠ FF-40-40ᶠᶠ FF-40-40ᶠᶠ FF-40-40ᶠᶠ FF-40-40ᶠᶠ 40-40-40⁰⁰ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ FF-40-40⁸⁸ FF-40-40ᶠᶠ FF-40-40ᶠᶠ FF-40-40⁸⁸ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰
|
||||
`;
|
||||
|
||||
exports[`canvas color transformation > can apply more than one color transformation 1`] = `
|
||||
Visualization:
|
||||
|
||||
7777777777
|
||||
7779■■9777
|
||||
77■■■■■■77
|
||||
79■■99■■97
|
||||
7■■9779■■7
|
||||
7■■9779■■7
|
||||
79■■99■■97
|
||||
77■■■■■■77
|
||||
7779■■9777
|
||||
7777777777
|
||||
|
||||
Data:
|
||||
|
||||
40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 80-FF-FF⁸⁸ 80-FF-FFᶠᶠ 80-FF-FFᶠᶠ 80-FF-FF⁸⁸ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ 40-40-40⁰⁰ 80-FF-FFᶠᶠ 80-FF-FFᶠᶠ 80-FF-FFᶠᶠ 80-FF-FFᶠᶠ 80-FF-FFᶠᶠ 80-FF-FFᶠᶠ 40-40-40⁰⁰ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ 80-FF-FF⁸⁸ 80-FF-FFᶠᶠ 80-FF-FFᶠᶠ 80-FF-FF⁸⁸ 80-FF-FF⁸⁸ 80-FF-FFᶠᶠ 80-FF-FFᶠᶠ 80-FF-FF⁸⁸ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ 80-FF-FFᶠᶠ 80-FF-FFᶠᶠ 80-FF-FF⁸⁸ 40-40-40⁰⁰ 40-40-40⁰⁰ 80-FF-FF⁸⁸ 80-FF-FFᶠᶠ 80-FF-FFᶠᶠ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ 80-FF-FFᶠᶠ 80-FF-FFᶠᶠ 80-FF-FF⁸⁸ 40-40-40⁰⁰ 40-40-40⁰⁰ 80-FF-FF⁸⁸ 80-FF-FFᶠᶠ 80-FF-FFᶠᶠ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ 80-FF-FF⁸⁸ 80-FF-FFᶠᶠ 80-FF-FFᶠᶠ 80-FF-FF⁸⁸ 80-FF-FF⁸⁸ 80-FF-FFᶠᶠ 80-FF-FFᶠᶠ 80-FF-FF⁸⁸ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ 40-40-40⁰⁰ 80-FF-FFᶠᶠ 80-FF-FFᶠᶠ 80-FF-FFᶠᶠ 80-FF-FFᶠᶠ 80-FF-FFᶠᶠ 80-FF-FFᶠᶠ 40-40-40⁰⁰ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 80-FF-FF⁸⁸ 80-FF-FFᶠᶠ 80-FF-FFᶠᶠ 80-FF-FF⁸⁸ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰
|
||||
`;
|
||||
|
||||
exports[`canvas color transformation > lighten 1`] = `
|
||||
Visualization:
|
||||
|
||||
7777777777
|
||||
777E▵▵E777
|
||||
77▵▵▵▵▵▵77
|
||||
7E▵▵EE▵▵E7
|
||||
7▵▵E77E▵▵7
|
||||
7▵▵E77E▵▵7
|
||||
7E▵▵EE▵▵E7
|
||||
77▵▵▵▵▵▵77
|
||||
777E▵▵E777
|
||||
7777777777
|
||||
|
||||
Data:
|
||||
|
||||
40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ FF-80-80⁸⁸ FF-80-80ᶠᶠ FF-80-80ᶠᶠ FF-80-80⁸⁸ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ 40-40-40⁰⁰ FF-80-80ᶠᶠ FF-80-80ᶠᶠ FF-80-80ᶠᶠ FF-80-80ᶠᶠ FF-80-80ᶠᶠ FF-80-80ᶠᶠ 40-40-40⁰⁰ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ FF-80-80⁸⁸ FF-80-80ᶠᶠ FF-80-80ᶠᶠ FF-80-80⁸⁸ FF-80-80⁸⁸ FF-80-80ᶠᶠ FF-80-80ᶠᶠ FF-80-80⁸⁸ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ FF-80-80ᶠᶠ FF-80-80ᶠᶠ FF-80-80⁸⁸ 40-40-40⁰⁰ 40-40-40⁰⁰ FF-80-80⁸⁸ FF-80-80ᶠᶠ FF-80-80ᶠᶠ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ FF-80-80ᶠᶠ FF-80-80ᶠᶠ FF-80-80⁸⁸ 40-40-40⁰⁰ 40-40-40⁰⁰ FF-80-80⁸⁸ FF-80-80ᶠᶠ FF-80-80ᶠᶠ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ FF-80-80⁸⁸ FF-80-80ᶠᶠ FF-80-80ᶠᶠ FF-80-80⁸⁸ FF-80-80⁸⁸ FF-80-80ᶠᶠ FF-80-80ᶠᶠ FF-80-80⁸⁸ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ 40-40-40⁰⁰ FF-80-80ᶠᶠ FF-80-80ᶠᶠ FF-80-80ᶠᶠ FF-80-80ᶠᶠ FF-80-80ᶠᶠ FF-80-80ᶠᶠ 40-40-40⁰⁰ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ FF-80-80⁸⁸ FF-80-80ᶠᶠ FF-80-80ᶠᶠ FF-80-80⁸⁸ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰
|
||||
40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰ 40-40-40⁰⁰
|
||||
`;
|
||||
|
||||
exports[`canvas color transformation > spin hue 1`] = `
|
||||
Visualization:
|
||||
|
||||
|
||||
▩33▩
|
||||
333333
|
||||
▩33▩▩33▩
|
||||
33▩ ▩33
|
||||
33▩ ▩33
|
||||
▩33▩▩33▩
|
||||
333333
|
||||
▩33▩
|
||||
|
||||
|
||||
Data:
|
||||
|
||||
00-00-00⁰⁰ 00-00-00⁰⁰ 00-00-00⁰⁰ 00-00-00⁰⁰ 00-00-00⁰⁰ 00-00-00⁰⁰ 00-00-00⁰⁰ 00-00-00⁰⁰ 00-00-00⁰⁰ 00-00-00⁰⁰
|
||||
00-00-00⁰⁰ 00-00-00⁰⁰ 00-00-00⁰⁰ 00-FF-80⁸⁸ 00-FF-80ᶠᶠ 00-FF-80ᶠᶠ 00-FF-80⁸⁸ 00-00-00⁰⁰ 00-00-00⁰⁰ 00-00-00⁰⁰
|
||||
00-00-00⁰⁰ 00-00-00⁰⁰ 00-FF-80ᶠᶠ 00-FF-80ᶠᶠ 00-FF-80ᶠᶠ 00-FF-80ᶠᶠ 00-FF-80ᶠᶠ 00-FF-80ᶠᶠ 00-00-00⁰⁰ 00-00-00⁰⁰
|
||||
00-00-00⁰⁰ 00-FF-80⁸⁸ 00-FF-80ᶠᶠ 00-FF-80ᶠᶠ 00-FF-80⁸⁸ 00-FF-80⁸⁸ 00-FF-80ᶠᶠ 00-FF-80ᶠᶠ 00-FF-80⁸⁸ 00-00-00⁰⁰
|
||||
00-00-00⁰⁰ 00-FF-80ᶠᶠ 00-FF-80ᶠᶠ 00-FF-80⁸⁸ 00-00-00⁰⁰ 00-00-00⁰⁰ 00-FF-80⁸⁸ 00-FF-80ᶠᶠ 00-FF-80ᶠᶠ 00-00-00⁰⁰
|
||||
00-00-00⁰⁰ 00-FF-80ᶠᶠ 00-FF-80ᶠᶠ 00-FF-80⁸⁸ 00-00-00⁰⁰ 00-00-00⁰⁰ 00-FF-80⁸⁸ 00-FF-80ᶠᶠ 00-FF-80ᶠᶠ 00-00-00⁰⁰
|
||||
00-00-00⁰⁰ 00-FF-80⁸⁸ 00-FF-80ᶠᶠ 00-FF-80ᶠᶠ 00-FF-80⁸⁸ 00-FF-80⁸⁸ 00-FF-80ᶠᶠ 00-FF-80ᶠᶠ 00-FF-80⁸⁸ 00-00-00⁰⁰
|
||||
00-00-00⁰⁰ 00-00-00⁰⁰ 00-FF-80ᶠᶠ 00-FF-80ᶠᶠ 00-FF-80ᶠᶠ 00-FF-80ᶠᶠ 00-FF-80ᶠᶠ 00-FF-80ᶠᶠ 00-00-00⁰⁰ 00-00-00⁰⁰
|
||||
00-00-00⁰⁰ 00-00-00⁰⁰ 00-00-00⁰⁰ 00-FF-80⁸⁸ 00-FF-80ᶠᶠ 00-FF-80ᶠᶠ 00-FF-80⁸⁸ 00-00-00⁰⁰ 00-00-00⁰⁰ 00-00-00⁰⁰
|
||||
00-00-00⁰⁰ 00-00-00⁰⁰ 00-00-00⁰⁰ 00-00-00⁰⁰ 00-00-00⁰⁰ 00-00-00⁰⁰ 00-00-00⁰⁰ 00-00-00⁰⁰ 00-00-00⁰⁰ 00-00-00⁰⁰
|
||||
`;
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`Normalize > change grayscale image 1`] = `
|
||||
Visualization:
|
||||
|
||||
■5▦
|
||||
5▦A
|
||||
▦A□
|
||||
|
||||
Data:
|
||||
|
||||
00-00-00ᶠᶠ 55-55-55ᶠᶠ 80-80-80ᶠᶠ
|
||||
55-55-55ᶠᶠ 80-80-80ᶠᶠ AA-AA-AAᶠᶠ
|
||||
80-80-80ᶠᶠ AA-AA-AAᶠᶠ FF-FF-FFᶠᶠ
|
||||
`;
|
||||
|
||||
exports[`Normalize > change red/blue image 1`] = `
|
||||
Visualization:
|
||||
|
||||
■□▩
|
||||
E▸▰
|
||||
|
||||
Data:
|
||||
|
||||
00-00-00ᶠᶠ 7F-00-66ᶠᶠ 7F-00-66⁰⁰
|
||||
7F-00-00ᶠᶠ 00-00-66ᶠᶠ FF-00-FFᶠᶠ
|
||||
`;
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import { expect, test, describe } from "vitest";
|
||||
import png from "@jimp/js-png";
|
||||
import jpeg from "@jimp/js-jpeg";
|
||||
import { createJimp } from "@jimp/core";
|
||||
import "@jimp/test-utils/image-snapshot";
|
||||
|
||||
import { methods } from "./index.js";
|
||||
|
||||
const jimp = createJimp({ formats: [png, jpeg], plugins: [methods] });
|
||||
|
||||
describe("Brightness", function () {
|
||||
test("3x3 box blur matrix using convolute", async () => {
|
||||
const image = await jimp.read(__dirname + "/images/tiles.jpg");
|
||||
const output = await image.brightness(2).getBuffer("image/png");
|
||||
|
||||
expect(output).toMatchImageSnapshot();
|
||||
});
|
||||
});
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
import { expect, test, describe } from "vitest";
|
||||
import png from "@jimp/js-png";
|
||||
import jpeg from "@jimp/js-jpeg";
|
||||
import { createJimp } from "@jimp/core";
|
||||
import "@jimp/test-utils/image-snapshot";
|
||||
|
||||
import { methods } from "./index.js";
|
||||
|
||||
const jimp = createJimp({ formats: [png, jpeg], plugins: [methods] });
|
||||
|
||||
describe("Convolution", function () {
|
||||
const blurM = [
|
||||
[1 / 9, 1 / 9, 1 / 9],
|
||||
[1 / 9, 1 / 9, 1 / 9],
|
||||
[1 / 9, 1 / 9, 1 / 9],
|
||||
];
|
||||
|
||||
test("3x3 box blur matrix using convolute", async () => {
|
||||
const image = await jimp.read(__dirname + "/images/tiles.jpg");
|
||||
const output = await image.convolute(blurM).getBuffer("image/png");
|
||||
|
||||
expect(output).toMatchImageSnapshot();
|
||||
});
|
||||
|
||||
test("new pixel value is greater than 255", async () => {
|
||||
const image = await jimp.read(__dirname + "/images/qr.jpg");
|
||||
|
||||
const convolutionMatrix = [
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 1, 1, 1, 0],
|
||||
[0, 1, 0, 1, 0],
|
||||
[0, 1, 1, 1, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
];
|
||||
|
||||
const output = await image
|
||||
.convolution(convolutionMatrix)
|
||||
.getBuffer("image/png");
|
||||
|
||||
expect(output).toMatchImageSnapshot();
|
||||
});
|
||||
});
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
import { expect, test, describe } from "vitest";
|
||||
import { makeTestImage } from "@jimp/test-utils";
|
||||
import png from "@jimp/js-png";
|
||||
import jpeg from "@jimp/js-jpeg";
|
||||
import { Edge } from "@jimp/types";
|
||||
import { createJimp } from "@jimp/core";
|
||||
|
||||
import { methods } from "./index.js";
|
||||
|
||||
const jimp = createJimp({ formats: [png, jpeg], plugins: [methods] });
|
||||
|
||||
describe("Convolution", function () {
|
||||
const imgMid = jimp.fromBitmap(
|
||||
makeTestImage(
|
||||
"22222222",
|
||||
"22222222",
|
||||
"22888822",
|
||||
"22888822",
|
||||
"22888822",
|
||||
"22888822",
|
||||
"22222222",
|
||||
"22222222",
|
||||
),
|
||||
);
|
||||
/** stores the Jimp instances of the JGD images above. */
|
||||
const imgTopLeft = jimp.fromBitmap(
|
||||
makeTestImage(
|
||||
"88222222",
|
||||
"88222222",
|
||||
"22222222",
|
||||
"22222222",
|
||||
"22222222",
|
||||
"22222222",
|
||||
"22222222",
|
||||
"22222222",
|
||||
),
|
||||
);
|
||||
|
||||
const sharpM = [
|
||||
[-1, -1, 0],
|
||||
[-1, 1, 1],
|
||||
[0, 1, 1],
|
||||
];
|
||||
|
||||
test("3x3 sharp matrix on EDGE_EXTEND", () => {
|
||||
expect(imgMid.clone().convolution(sharpM)).toMatchSnapshot();
|
||||
expect(imgTopLeft.clone().convolution(sharpM)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("3x3 sharp matrix on EDGE_WRAP", () => {
|
||||
expect(
|
||||
imgMid.clone().convolution({ kernel: sharpM, edgeHandling: Edge.WRAP }),
|
||||
).toMatchSnapshot();
|
||||
expect(
|
||||
imgTopLeft
|
||||
.clone()
|
||||
.convolution({ kernel: sharpM, edgeHandling: Edge.WRAP }),
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("3x3 sharp matrix on EDGE_CROP", () => {
|
||||
expect(
|
||||
imgMid.clone().convolution({ kernel: sharpM, edgeHandling: Edge.CROP }),
|
||||
).toMatchSnapshot();
|
||||
expect(
|
||||
imgTopLeft
|
||||
.clone()
|
||||
.convolution({ kernel: sharpM, edgeHandling: Edge.CROP }),
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 103 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 5.6 KiB |
+63
@@ -0,0 +1,63 @@
|
||||
import { expect, test, describe } from "vitest";
|
||||
|
||||
import { makeDonutTestImage } from "@jimp/test-utils";
|
||||
import { createJimp } from "@jimp/core";
|
||||
|
||||
import { methods as color } from "./index.js";
|
||||
|
||||
const jimp = createJimp({ plugins: [color] });
|
||||
|
||||
describe("canvas color transformation", () => {
|
||||
const redDonutJGD = makeDonutTestImage(0x00000000, 0xff000088, 0xff0000ff);
|
||||
|
||||
test("can apply more than one color transformation", () => {
|
||||
const image = jimp.fromBitmap(redDonutJGD);
|
||||
const newJGD = image.color([
|
||||
{ apply: "hue", params: [-180] },
|
||||
{ apply: "lighten", params: [25] },
|
||||
]);
|
||||
|
||||
expect(newJGD.bitmap).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("lighten", () => {
|
||||
const image = jimp.fromBitmap(redDonutJGD);
|
||||
expect(image.color([{ apply: "lighten", params: [25] }])).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("brighten", () => {
|
||||
const image = jimp.fromBitmap(redDonutJGD);
|
||||
expect(
|
||||
image.color([{ apply: "brighten", params: [25] }]),
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("spin hue", () => {
|
||||
const image = jimp.fromBitmap(redDonutJGD);
|
||||
expect(image.color([{ apply: "hue", params: [150] }])).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe("brightness", () => {
|
||||
test("brightness of 1 should be the same as no change", () => {
|
||||
const jgd = makeDonutTestImage(0xff000088, 0xff000088, 0xff000088);
|
||||
const image = jimp.fromBitmap(jgd);
|
||||
const image2 = jimp.fromBitmap(jgd);
|
||||
|
||||
expect(image.brightness(1).bitmap).toStrictEqual(image2.bitmap);
|
||||
});
|
||||
|
||||
test("should be able to brighten", () => {
|
||||
const jgd = makeDonutTestImage(0xaa000088, 0xaa000088, 0xaa000088);
|
||||
const image = jimp.fromBitmap(jgd);
|
||||
|
||||
expect(image.brightness(2).bitmap).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("should be able to darken", () => {
|
||||
const jgd = makeDonutTestImage(0xaa000088, 0xaa000088, 0xaa000088);
|
||||
const image = jimp.fromBitmap(jgd);
|
||||
|
||||
expect(image.brightness(0.2).bitmap).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
+863
@@ -0,0 +1,863 @@
|
||||
import tinyColor from "tinycolor2";
|
||||
import { clone, limit255, scan } from "@jimp/utils";
|
||||
import { Edge, JimpClass, RGBColor } from "@jimp/types";
|
||||
import { z } from "zod";
|
||||
|
||||
const ConvolutionMatrixSchema = z.array(z.number()).min(1).array();
|
||||
const ConvolutionComplexOptionsSchema = z.object({
|
||||
/** a matrix to weight the neighbors sum */
|
||||
kernel: ConvolutionMatrixSchema,
|
||||
/**define how to sum pixels from outside the border */
|
||||
edgeHandling: z.nativeEnum(Edge).optional(),
|
||||
});
|
||||
const ConvolutionOptionsSchema = z.union([
|
||||
ConvolutionMatrixSchema,
|
||||
ConvolutionComplexOptionsSchema,
|
||||
]);
|
||||
|
||||
type ConvolutionOptions = z.infer<typeof ConvolutionOptionsSchema>;
|
||||
|
||||
const ConvoluteComplexOptionsSchema = z.object({
|
||||
/** the convolution kernel */
|
||||
kernel: ConvolutionMatrixSchema,
|
||||
/** the x position of the region to apply convolution to */
|
||||
x: z.number().optional(),
|
||||
/** the y position of the region to apply convolution to */
|
||||
y: z.number().optional(),
|
||||
/** the width of the region to apply convolution to */
|
||||
w: z.number().optional(),
|
||||
/** the height of the region to apply convolution to */
|
||||
h: z.number().optional(),
|
||||
});
|
||||
const ConvoluteOptionsSchema = z.union([
|
||||
ConvolutionMatrixSchema,
|
||||
ConvoluteComplexOptionsSchema,
|
||||
]);
|
||||
|
||||
type ConvoluteComplexOptions = z.infer<typeof ConvoluteComplexOptionsSchema>;
|
||||
type ConvoluteOptions = z.infer<typeof ConvoluteOptionsSchema>;
|
||||
|
||||
const PixelateSize = z.number().min(1).max(Infinity);
|
||||
const PixelateComplexOptionsSchema = z.object({
|
||||
/** the size of the pixels */
|
||||
size: PixelateSize,
|
||||
/** the x position of the region to pixelate */
|
||||
x: z.number().optional(),
|
||||
/** the y position of the region to pixelate */
|
||||
y: z.number().optional(),
|
||||
/** the width of the region to pixelate */
|
||||
w: z.number().optional(),
|
||||
/** the height of the region to pixelate */
|
||||
h: z.number().optional(),
|
||||
});
|
||||
const PixelateOptionsSchema = z.union([
|
||||
PixelateSize,
|
||||
PixelateComplexOptionsSchema,
|
||||
]);
|
||||
|
||||
type PixelateComplexOptions = z.infer<typeof PixelateComplexOptionsSchema>;
|
||||
type PixelateOptions = z.infer<typeof PixelateOptionsSchema>;
|
||||
|
||||
function applyKernel(
|
||||
image: JimpClass,
|
||||
kernel: number[][],
|
||||
x: number,
|
||||
y: number,
|
||||
) {
|
||||
const value = [0, 0, 0, 0] as [number, number, number, number];
|
||||
const size = (kernel.length - 1) / 2;
|
||||
|
||||
for (let kx = 0; kx < kernel.length; kx += 1) {
|
||||
for (let ky = 0; ky < kernel[kx]!.length; ky += 1) {
|
||||
const idx = image.getPixelIndex(x + kx - size, y + ky - size);
|
||||
|
||||
value[0] += image.bitmap.data[idx]! * kernel[kx]![ky]!;
|
||||
value[1] += image.bitmap.data[idx + 1]! * kernel[kx]![ky]!;
|
||||
value[2] += image.bitmap.data[idx + 2]! * kernel[kx]![ky]!;
|
||||
value[3] += image.bitmap.data[idx + 3]! * kernel[kx]![ky]!;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
function mix(clr: RGBColor, clr2: RGBColor, p = 50) {
|
||||
return {
|
||||
r: (clr2.r - clr.r) * (p / 100) + clr.r,
|
||||
g: (clr2.g - clr.g) * (p / 100) + clr.g,
|
||||
b: (clr2.b - clr.b) * (p / 100) + clr.b,
|
||||
};
|
||||
}
|
||||
|
||||
const HueActionSchema = z.object({
|
||||
apply: z.literal("hue"),
|
||||
params: z.tuple([z.number().min(-360).max(360)]),
|
||||
});
|
||||
export type HueAction = z.infer<typeof HueActionSchema>;
|
||||
|
||||
const SpinActionSchema = z.object({
|
||||
apply: z.literal("spin"),
|
||||
params: z.tuple([z.number().min(-360).max(360)]),
|
||||
});
|
||||
export type SpinAction = z.infer<typeof SpinActionSchema>;
|
||||
|
||||
const LightenActionSchema = z.object({
|
||||
apply: z.literal("lighten"),
|
||||
params: z.tuple([z.number().min(0).max(100)]).optional(),
|
||||
});
|
||||
export type LightenAction = z.infer<typeof LightenActionSchema>;
|
||||
|
||||
const RGBColorSchema = z.object({
|
||||
r: z.number().min(0).max(255),
|
||||
g: z.number().min(0).max(255),
|
||||
b: z.number().min(0).max(255),
|
||||
});
|
||||
|
||||
const MixActionSchema = z.object({
|
||||
apply: z.literal("mix"),
|
||||
params: z.union([
|
||||
z.tuple([RGBColorSchema]),
|
||||
z.tuple([RGBColorSchema, z.number().min(0).max(100)]),
|
||||
]),
|
||||
});
|
||||
export type MixAction = z.infer<typeof MixActionSchema>;
|
||||
|
||||
const TintActionSchema = z.object({
|
||||
apply: z.literal("tint"),
|
||||
params: z.tuple([z.number().min(0).max(100)]).optional(),
|
||||
});
|
||||
export type TintAction = z.infer<typeof TintActionSchema>;
|
||||
|
||||
const ShadeActionSchema = z.object({
|
||||
apply: z.literal("shade"),
|
||||
params: z.tuple([z.number().min(0).max(100)]).optional(),
|
||||
});
|
||||
export type ShadeAction = z.infer<typeof ShadeActionSchema>;
|
||||
|
||||
const XorActionSchema = z.object({
|
||||
apply: z.literal("xor"),
|
||||
params: z.tuple([RGBColorSchema]),
|
||||
});
|
||||
export type XorAction = z.infer<typeof XorActionSchema>;
|
||||
|
||||
const RedActionSchema = z.object({
|
||||
apply: z.literal("red"),
|
||||
params: z.tuple([z.number().min(-255).max(255)]),
|
||||
});
|
||||
export type RedAction = z.infer<typeof RedActionSchema>;
|
||||
|
||||
const GreenActionSchema = z.object({
|
||||
apply: z.literal("green"),
|
||||
params: z.tuple([z.number().min(-255).max(255)]),
|
||||
});
|
||||
export type GreenAction = z.infer<typeof GreenActionSchema>;
|
||||
|
||||
const BlueActionSchema = z.object({
|
||||
apply: z.literal("blue"),
|
||||
params: z.tuple([z.number().min(-255).max(255)]),
|
||||
});
|
||||
export type BlueAction = z.infer<typeof BlueActionSchema>;
|
||||
|
||||
const BrightenActionSchema = z.object({
|
||||
apply: z.literal("brighten"),
|
||||
params: z.tuple([z.number().min(0).max(100)]).optional(),
|
||||
});
|
||||
export type BrightenAction = z.infer<typeof BrightenActionSchema>;
|
||||
|
||||
const DarkenActionSchema = z.object({
|
||||
apply: z.literal("darken"),
|
||||
params: z.tuple([z.number().min(0).max(100)]).optional(),
|
||||
});
|
||||
export type DarkenAction = z.infer<typeof DarkenActionSchema>;
|
||||
|
||||
const DesaturateActionSchema = z.object({
|
||||
apply: z.literal("desaturate"),
|
||||
params: z.tuple([z.number().min(0).max(100)]).optional(),
|
||||
});
|
||||
export type DesaturateAction = z.infer<typeof DesaturateActionSchema>;
|
||||
|
||||
const SaturateActionSchema = z.object({
|
||||
apply: z.literal("saturate"),
|
||||
params: z.tuple([z.number().min(0).max(100)]).optional(),
|
||||
});
|
||||
export type SaturateAction = z.infer<typeof SaturateActionSchema>;
|
||||
|
||||
const GrayscaleActionSchema = z.object({
|
||||
apply: z.literal("greyscale"),
|
||||
params: z.tuple([]).optional(),
|
||||
});
|
||||
export type GrayscaleAction = z.infer<typeof GrayscaleActionSchema>;
|
||||
|
||||
const ColorActionNameSchema = z.union([
|
||||
HueActionSchema,
|
||||
SpinActionSchema,
|
||||
LightenActionSchema,
|
||||
MixActionSchema,
|
||||
TintActionSchema,
|
||||
ShadeActionSchema,
|
||||
XorActionSchema,
|
||||
RedActionSchema,
|
||||
GreenActionSchema,
|
||||
BlueActionSchema,
|
||||
BrightenActionSchema,
|
||||
DarkenActionSchema,
|
||||
DesaturateActionSchema,
|
||||
SaturateActionSchema,
|
||||
GrayscaleActionSchema,
|
||||
]);
|
||||
export type ColorAction = z.infer<typeof ColorActionNameSchema>;
|
||||
|
||||
export const ColorActionName = Object.freeze({
|
||||
LIGHTEN: "lighten",
|
||||
BRIGHTEN: "brighten",
|
||||
DARKEN: "darken",
|
||||
DESATURATE: "desaturate",
|
||||
SATURATE: "saturate",
|
||||
GREYSCALE: "greyscale",
|
||||
SPIN: "spin",
|
||||
HUE: "hue",
|
||||
MIX: "mix",
|
||||
TINT: "tint",
|
||||
SHADE: "shade",
|
||||
XOR: "xor",
|
||||
RED: "red",
|
||||
GREEN: "green",
|
||||
BLUE: "blue",
|
||||
});
|
||||
|
||||
/**
|
||||
* Get an image's histogram
|
||||
* @return An object with an array of color occurrence counts for each channel (r,g,b)
|
||||
*/
|
||||
function histogram<I extends JimpClass>(image: I) {
|
||||
const histogram = {
|
||||
r: new Array<number>(256).fill(0),
|
||||
g: new Array<number>(256).fill(0),
|
||||
b: new Array<number>(256).fill(0),
|
||||
};
|
||||
|
||||
image.scan((_, __, index) => {
|
||||
histogram.r[image.bitmap.data[index + 0]!]!++;
|
||||
histogram.g[image.bitmap.data[index + 1]!]!++;
|
||||
histogram.b[image.bitmap.data[index + 2]!]!++;
|
||||
});
|
||||
|
||||
return histogram;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize values
|
||||
* @param value Pixel channel value.
|
||||
* @param min Minimum value for channel
|
||||
* @param max Maximum value for channel
|
||||
*/
|
||||
const normalizeValue = function (value: number, min: number, max: number) {
|
||||
return ((value - min) * 255) / (max - min);
|
||||
};
|
||||
|
||||
const getBounds = function (histogramChannel: number[]) {
|
||||
return [
|
||||
histogramChannel.findIndex((value) => value > 0),
|
||||
255 -
|
||||
histogramChannel
|
||||
.slice()
|
||||
.reverse()
|
||||
.findIndex((value) => value > 0),
|
||||
];
|
||||
};
|
||||
|
||||
export const methods = {
|
||||
/**
|
||||
* Normalizes the image.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.normalize();
|
||||
* ```
|
||||
*/
|
||||
normalize<I extends JimpClass>(image: I) {
|
||||
const h = histogram(image);
|
||||
|
||||
// store bounds (minimum and maximum values)
|
||||
const bounds = {
|
||||
r: getBounds(h.r),
|
||||
g: getBounds(h.g),
|
||||
b: getBounds(h.b),
|
||||
};
|
||||
|
||||
// apply value transformations
|
||||
image.scan((_, __, idx) => {
|
||||
const r = image.bitmap.data[idx + 0]!;
|
||||
const g = image.bitmap.data[idx + 1]!;
|
||||
const b = image.bitmap.data[idx + 2]!;
|
||||
|
||||
image.bitmap.data[idx + 0] = normalizeValue(
|
||||
r,
|
||||
bounds.r[0]!,
|
||||
bounds.r[1]!,
|
||||
);
|
||||
image.bitmap.data[idx + 1] = normalizeValue(
|
||||
g,
|
||||
bounds.g[0]!,
|
||||
bounds.g[1]!,
|
||||
);
|
||||
image.bitmap.data[idx + 2] = normalizeValue(
|
||||
b,
|
||||
bounds.b[0]!,
|
||||
bounds.b[1]!,
|
||||
);
|
||||
});
|
||||
|
||||
return image;
|
||||
},
|
||||
|
||||
/**
|
||||
* Inverts the colors in the image.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.invert();
|
||||
* ```
|
||||
*/
|
||||
invert<I extends JimpClass>(image: I) {
|
||||
image.scan((_, __, idx) => {
|
||||
image.bitmap.data[idx] = 255 - image.bitmap.data[idx]!;
|
||||
image.bitmap.data[idx + 1] = 255 - image.bitmap.data[idx + 1]!;
|
||||
image.bitmap.data[idx + 2] = 255 - image.bitmap.data[idx + 2]!;
|
||||
});
|
||||
|
||||
return image;
|
||||
},
|
||||
|
||||
/**
|
||||
* Adjusts the brightness of the image
|
||||
* @param val the amount to adjust the brightness.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.brightness(0.5);
|
||||
* ```
|
||||
*/
|
||||
brightness<I extends JimpClass>(image: I, val: number) {
|
||||
if (typeof val !== "number") {
|
||||
throw new Error("val must be numbers");
|
||||
}
|
||||
|
||||
image.scan((_, __, idx) => {
|
||||
image.bitmap.data[idx]! = limit255(image.bitmap.data[idx]! * val);
|
||||
image.bitmap.data[idx + 1]! = limit255(image.bitmap.data[idx + 1]! * val);
|
||||
image.bitmap.data[idx + 2]! = limit255(image.bitmap.data[idx + 2]! * val);
|
||||
});
|
||||
|
||||
return image;
|
||||
},
|
||||
|
||||
/**
|
||||
* Adjusts the contrast of the image
|
||||
* @param val the amount to adjust the contrast, a number between -1 and +1
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.contrast(0.75);
|
||||
* ```
|
||||
*/
|
||||
contrast<I extends JimpClass>(image: I, val: number) {
|
||||
if (typeof val !== "number") {
|
||||
throw new Error("val must be numbers");
|
||||
}
|
||||
|
||||
if (val < -1 || val > +1) {
|
||||
throw new Error("val must be a number between -1 and +1");
|
||||
}
|
||||
|
||||
const factor = (val + 1) / (1 - val);
|
||||
|
||||
function adjust(value: number) {
|
||||
value = Math.floor(factor * (value - 127) + 127);
|
||||
return value < 0 ? 0 : value > 255 ? 255 : value;
|
||||
}
|
||||
|
||||
image.scan((_, __, idx) => {
|
||||
image.bitmap.data[idx] = adjust(image.bitmap.data[idx]!);
|
||||
image.bitmap.data[idx + 1] = adjust(image.bitmap.data[idx + 1]!);
|
||||
image.bitmap.data[idx + 2] = adjust(image.bitmap.data[idx + 2]!);
|
||||
});
|
||||
|
||||
return image;
|
||||
},
|
||||
|
||||
/**
|
||||
* Apply a posterize effect
|
||||
* @param n the amount to adjust the contrast, minimum threshold is two
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.posterize(5);
|
||||
* ```
|
||||
*/
|
||||
posterize<I extends JimpClass>(image: I, n: number) {
|
||||
if (typeof n !== "number") {
|
||||
throw new Error("n must be numbers");
|
||||
}
|
||||
|
||||
// minimum of 2 levels
|
||||
if (n < 2) {
|
||||
n = 2;
|
||||
}
|
||||
|
||||
image.scan((_, __, idx) => {
|
||||
const r = image.bitmap.data[idx]!;
|
||||
const g = image.bitmap.data[idx + 1]!;
|
||||
const b = image.bitmap.data[idx + 2]!;
|
||||
|
||||
image.bitmap.data[idx] =
|
||||
(Math.floor((r / 255) * (n - 1)) / (n - 1)) * 255;
|
||||
image.bitmap.data[idx + 1] =
|
||||
(Math.floor((g / 255) * (n - 1)) / (n - 1)) * 255;
|
||||
image.bitmap.data[idx + 2] =
|
||||
(Math.floor((b / 255) * (n - 1)) / (n - 1)) * 255;
|
||||
});
|
||||
|
||||
return image;
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes colour from the image using ITU Rec 709 luminance values
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.greyscale();
|
||||
* ```
|
||||
*/
|
||||
greyscale<I extends JimpClass>(image: I) {
|
||||
image.scan((_, __, idx) => {
|
||||
// const grey = parseInt(
|
||||
// 0.2126 * image.bitmap.data[idx]! +
|
||||
// 0.7152 * image.bitmap.data[idx + 1]! +
|
||||
// 0.0722 * image.bitmap.data[idx + 2]!,
|
||||
// 10
|
||||
// );
|
||||
const grey =
|
||||
0.2126 * image.bitmap.data[idx]! +
|
||||
0.7152 * image.bitmap.data[idx + 1]! +
|
||||
0.0722 * image.bitmap.data[idx + 2]!;
|
||||
|
||||
image.bitmap.data[idx] = grey;
|
||||
image.bitmap.data[idx + 1] = grey;
|
||||
image.bitmap.data[idx + 2] = grey;
|
||||
});
|
||||
|
||||
return image;
|
||||
},
|
||||
|
||||
/**
|
||||
* Multiplies the opacity of each pixel by a factor between 0 and 1
|
||||
* @param f A number, the factor by which to multiply the opacity of each pixel
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.opacity(0.5);
|
||||
* ```
|
||||
*/
|
||||
opacity<I extends JimpClass>(image: I, f: number) {
|
||||
if (typeof f !== "number") {
|
||||
throw new Error("f must be a number");
|
||||
}
|
||||
|
||||
if (f < 0 || f > 1) {
|
||||
throw new Error("f must be a number from 0 to 1");
|
||||
}
|
||||
|
||||
image.scan((_, __, idx) => {
|
||||
const v = image.bitmap.data[idx + 3]! * f;
|
||||
image.bitmap.data[idx + 3] = v;
|
||||
});
|
||||
|
||||
return image;
|
||||
},
|
||||
|
||||
/**
|
||||
* Applies a sepia tone to the image.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.sepia();
|
||||
* ```
|
||||
*/
|
||||
sepia<I extends JimpClass>(image: I) {
|
||||
image.scan((_, __, idx) => {
|
||||
let red = image.bitmap.data[idx]!;
|
||||
let green = image.bitmap.data[idx + 1]!;
|
||||
let blue = image.bitmap.data[idx + 2]!;
|
||||
|
||||
red = red * 0.393 + green * 0.769 + blue * 0.189;
|
||||
green = red * 0.349 + green * 0.686 + blue * 0.168;
|
||||
blue = red * 0.272 + green * 0.534 + blue * 0.131;
|
||||
|
||||
image.bitmap.data[idx] = red < 255 ? red : 255;
|
||||
image.bitmap.data[idx + 1] = green < 255 ? green : 255;
|
||||
image.bitmap.data[idx + 2] = blue < 255 ? blue : 255;
|
||||
});
|
||||
|
||||
return image;
|
||||
},
|
||||
|
||||
/**
|
||||
* Fades each pixel by a factor between 0 and 1
|
||||
* @param f A number from 0 to 1. 0 will haven no effect. 1 will turn the image completely transparent.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.fade(0.7);
|
||||
* ```
|
||||
*/
|
||||
fade<I extends JimpClass>(image: I, f: number) {
|
||||
if (typeof f !== "number") {
|
||||
throw new Error("f must be a number");
|
||||
}
|
||||
|
||||
if (f < 0 || f > 1) {
|
||||
throw new Error("f must be a number from 0 to 1");
|
||||
}
|
||||
|
||||
// this method is an alternative to opacity (which may be deprecated)
|
||||
return this.opacity(image, 1 - f);
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds each element of the image to its local neighbors, weighted by the kernel
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.convolute([
|
||||
* [-1, -1, 0],
|
||||
* [-1, 1, 1],
|
||||
* [0, 1, 1],
|
||||
* ]);
|
||||
* ```
|
||||
*/
|
||||
convolution<I extends JimpClass>(image: I, options: ConvolutionOptions) {
|
||||
const parsed = ConvolutionOptionsSchema.parse(options);
|
||||
const { kernel, edgeHandling = Edge.EXTEND } =
|
||||
"kernel" in parsed ? parsed : { kernel: parsed, edgeHandling: undefined };
|
||||
|
||||
if (!kernel[0]) {
|
||||
throw new Error("kernel must be a matrix");
|
||||
}
|
||||
|
||||
const newData = Buffer.from(image.bitmap.data);
|
||||
const kRows = kernel.length;
|
||||
const kCols = kernel[0].length;
|
||||
const rowEnd = Math.floor(kRows / 2);
|
||||
const colEnd = Math.floor(kCols / 2);
|
||||
const rowIni = -rowEnd;
|
||||
const colIni = -colEnd;
|
||||
|
||||
let weight;
|
||||
let rSum;
|
||||
let gSum;
|
||||
let bSum;
|
||||
let ri;
|
||||
let gi;
|
||||
let bi;
|
||||
let xi;
|
||||
let yi;
|
||||
let idxi;
|
||||
|
||||
image.scan((x, y, idx) => {
|
||||
bSum = 0;
|
||||
gSum = 0;
|
||||
rSum = 0;
|
||||
|
||||
for (let row = rowIni; row <= rowEnd; row++) {
|
||||
for (let col = colIni; col <= colEnd; col++) {
|
||||
xi = x + col;
|
||||
yi = y + row;
|
||||
weight = kernel[row + rowEnd]![col + colEnd]!;
|
||||
idxi = image.getPixelIndex(xi, yi, edgeHandling);
|
||||
|
||||
if (idxi === -1) {
|
||||
bi = 0;
|
||||
gi = 0;
|
||||
ri = 0;
|
||||
} else {
|
||||
ri = image.bitmap.data[idxi + 0]!;
|
||||
gi = image.bitmap.data[idxi + 1]!;
|
||||
bi = image.bitmap.data[idxi + 2]!;
|
||||
}
|
||||
|
||||
rSum += weight * ri;
|
||||
gSum += weight * gi;
|
||||
bSum += weight * bi;
|
||||
}
|
||||
}
|
||||
|
||||
if (rSum < 0) {
|
||||
rSum = 0;
|
||||
}
|
||||
|
||||
if (gSum < 0) {
|
||||
gSum = 0;
|
||||
}
|
||||
|
||||
if (bSum < 0) {
|
||||
bSum = 0;
|
||||
}
|
||||
|
||||
if (rSum > 255) {
|
||||
rSum = 255;
|
||||
}
|
||||
|
||||
if (gSum > 255) {
|
||||
gSum = 255;
|
||||
}
|
||||
|
||||
if (bSum > 255) {
|
||||
bSum = 255;
|
||||
}
|
||||
|
||||
newData[idx + 0] = rSum;
|
||||
newData[idx + 1] = gSum;
|
||||
newData[idx + 2] = bSum;
|
||||
});
|
||||
|
||||
image.bitmap.data = newData;
|
||||
|
||||
return image;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the alpha channel on every pixel to fully opaque.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.opaque();
|
||||
* ```
|
||||
*/
|
||||
opaque<I extends JimpClass>(image: I) {
|
||||
image.scan((_, __, idx) => {
|
||||
image.bitmap.data[idx + 3] = 255;
|
||||
});
|
||||
|
||||
return image;
|
||||
},
|
||||
|
||||
/**
|
||||
* Pixelates the image or a region
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* // pixelate the whole image
|
||||
* image.pixelate(10);
|
||||
*
|
||||
* // pixelate a region
|
||||
* image.pixelate(10, 10, 10, 20, 20);
|
||||
* ```
|
||||
*/
|
||||
pixelate<I extends JimpClass>(image: I, options: PixelateOptions) {
|
||||
const parsed = PixelateOptionsSchema.parse(options);
|
||||
const {
|
||||
size,
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = image.bitmap.width - x,
|
||||
h = image.bitmap.height - y,
|
||||
} = typeof parsed === "number"
|
||||
? ({ size: parsed } as PixelateComplexOptions)
|
||||
: parsed;
|
||||
|
||||
const kernel = [
|
||||
[1 / 16, 2 / 16, 1 / 16],
|
||||
[2 / 16, 4 / 16, 2 / 16],
|
||||
[1 / 16, 2 / 16, 1 / 16],
|
||||
];
|
||||
|
||||
const source = clone(image);
|
||||
|
||||
scan(source, x, y, w, h, (xx, yx, idx) => {
|
||||
xx = size * Math.floor(xx / size);
|
||||
yx = size * Math.floor(yx / size);
|
||||
|
||||
const value = applyKernel(source, kernel, xx, yx);
|
||||
|
||||
image.bitmap.data[idx] = value[0]!;
|
||||
image.bitmap.data[idx + 1] = value[1]!;
|
||||
image.bitmap.data[idx + 2] = value[2]!;
|
||||
image.bitmap.data[idx + 3] = value[3]!;
|
||||
});
|
||||
|
||||
return image;
|
||||
},
|
||||
|
||||
/**
|
||||
* Applies a convolution kernel to the image or a region
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* // apply a convolution kernel to the whole image
|
||||
* image.convolution([
|
||||
* [-1, -1, 0],
|
||||
* [-1, 1, 1],
|
||||
* [0, 1, 1],
|
||||
* ]);
|
||||
*
|
||||
* // apply a convolution kernel to a region
|
||||
* image.convolution([
|
||||
* [-1, -1, 0],
|
||||
* [-1, 1, 1],
|
||||
* [0, 1, 1],
|
||||
* ], 10, 10, 10, 20);
|
||||
* ```
|
||||
*/
|
||||
convolute<I extends JimpClass>(image: I, options: ConvoluteOptions) {
|
||||
const parsed = ConvoluteOptionsSchema.parse(options);
|
||||
const {
|
||||
kernel,
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = image.bitmap.width - x,
|
||||
h = image.bitmap.height - y,
|
||||
} = "kernel" in parsed
|
||||
? parsed
|
||||
: ({ kernel: parsed } as ConvoluteComplexOptions);
|
||||
|
||||
const source = clone(image);
|
||||
|
||||
scan(source, x, y, w, h, (xx, yx, idx) => {
|
||||
const value = applyKernel(source, kernel, xx, yx);
|
||||
|
||||
image.bitmap.data[idx] = limit255(value[0]!);
|
||||
image.bitmap.data[idx + 1] = limit255(value[1]!);
|
||||
image.bitmap.data[idx + 2] = limit255(value[2]!);
|
||||
image.bitmap.data[idx + 3] = limit255(value[3]!);
|
||||
});
|
||||
|
||||
return image;
|
||||
},
|
||||
|
||||
/**
|
||||
* Apply multiple color modification rules
|
||||
* @param actions list of color modification rules, in following format: { apply: '<rule-name>', params: [ <rule-parameters> ] }
|
||||
* @example
|
||||
* ```ts
|
||||
* import { Jimp } from "jimp";
|
||||
*
|
||||
* const image = await Jimp.read("test/image.png");
|
||||
*
|
||||
* image.color([
|
||||
* { apply: "hue", params: [-90] },
|
||||
* { apply: "lighten", params: [50] },
|
||||
* { apply: "xor", params: ["#06D"] },
|
||||
* ]);
|
||||
* ```
|
||||
*/
|
||||
color<I extends JimpClass>(image: I, actions: ColorAction[]) {
|
||||
if (!actions || !Array.isArray(actions)) {
|
||||
throw new Error("actions must be an array");
|
||||
}
|
||||
|
||||
actions.forEach((action) => ColorActionNameSchema.parse(action));
|
||||
|
||||
actions = actions.map((action) => {
|
||||
if (action.apply === "xor" || action.apply === "mix") {
|
||||
action.params[0] = tinyColor(action.params[0]).toRgb();
|
||||
}
|
||||
|
||||
return action;
|
||||
});
|
||||
|
||||
image.scan((_, __, idx) => {
|
||||
let clr: RGBColor = {
|
||||
r: image.bitmap.data[idx]!,
|
||||
g: image.bitmap.data[idx + 1]!,
|
||||
b: image.bitmap.data[idx + 2]!,
|
||||
};
|
||||
|
||||
const colorModifier = (i: "r" | "g" | "b", amount: number) =>
|
||||
limit255(clr[i] + amount);
|
||||
|
||||
actions.forEach((action) => {
|
||||
if (action.apply === "mix") {
|
||||
clr = mix(clr, action.params[0], action.params[1]);
|
||||
} else if (action.apply === "tint") {
|
||||
clr = mix(clr, { r: 255, g: 255, b: 255 }, action.params?.[0]);
|
||||
} else if (action.apply === "shade") {
|
||||
clr = mix(clr, { r: 0, g: 0, b: 0 }, action.params?.[0]);
|
||||
} else if (action.apply === "xor") {
|
||||
clr = {
|
||||
r: clr.r! ^ action.params[0].r,
|
||||
g: clr.g! ^ action.params[0].g,
|
||||
b: clr.b! ^ action.params[0].b,
|
||||
};
|
||||
} else if (action.apply === "red") {
|
||||
clr.r = colorModifier("r", action.params[0]);
|
||||
} else if (action.apply === "green") {
|
||||
clr.g = colorModifier("g", action.params[0]);
|
||||
} else if (action.apply === "blue") {
|
||||
clr.b = colorModifier("b", action.params[0]);
|
||||
} else {
|
||||
if (action.apply === "hue") {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
action.apply = "spin";
|
||||
}
|
||||
|
||||
const tnyClr = tinyColor(clr);
|
||||
const fn = tnyClr[action.apply].bind(tnyClr);
|
||||
|
||||
if (!fn) {
|
||||
throw new Error("action " + action.apply + " not supported");
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
clr = (fn as any)(...(action.params || [])).toRgb();
|
||||
}
|
||||
});
|
||||
|
||||
image.bitmap.data[idx] = clr.r;
|
||||
image.bitmap.data[idx + 1] = clr.g;
|
||||
image.bitmap.data[idx + 2] = clr.b;
|
||||
});
|
||||
|
||||
return image;
|
||||
},
|
||||
};
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
import { expect, test, describe } from "vitest";
|
||||
|
||||
import { makeTestImage } from "@jimp/test-utils";
|
||||
|
||||
import { methods } from "./index.js";
|
||||
import { createJimp } from "@jimp/core";
|
||||
|
||||
const jimp = createJimp({ plugins: [methods] });
|
||||
|
||||
describe("Normalize", () => {
|
||||
test("change grayscale image", () => {
|
||||
const image = jimp.fromBitmap(makeTestImage("36▦", "6▦9", "▦9C"));
|
||||
expect(image.normalize()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("change red/blue image", () => {
|
||||
const image = jimp.fromBitmap({
|
||||
width: 3,
|
||||
height: 2,
|
||||
data: [
|
||||
0x000000ff, 0x400022ff, 0x40002200, 0x400000ff, 0x000022ff, 0x800055ff,
|
||||
],
|
||||
});
|
||||
|
||||
expect(image.normalize()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": "@jimp/config-typescript/base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist"
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import config from "@jimp/config-vitest/browser";
|
||||
|
||||
export default config;
|
||||
Reference in new issue
Block a user