Imagizer is a JavaScript library for image manipulation written in TypeScript. It supports both node.js (with node-canvas dependency) and browser! Also console binary is available.
Imagizer effect algorithms are based on a Jerry's Java Image Proccesing Library
npm install imagizer
If you are using webpack in your project with imagizer you must add externals definitions to your webpack configuration:
{
'canvas': 'canvas',
'fs': 'fs'
}
This prevents from throwing errors when bundled script is trying to load backend libraries in your frontend environment.
To start an imagizer project:
import imagizer from "imagizer";
const project = new imagizer.Project(projectWidth, projectHeight);
const imagizer = require("imagizer");
const project = new imagizer.Project(projectWidth, projectHeight);
projectWidth and projectHeight are dimensions of result image.
To the project you can add layer:
const layer1 = project.createLayer({
blendingMode: "normal", // optional
});
To the layer you can add image:
const image1 = new Imagizer.Image();
image1.load("my-image.png", function () {
const onLayerObject = layer1.put(image1, 0, 0); // put image1 on the layer1 on position 0, 0 (left upper corner)
});
"my-image.png" is a path to the image
- in frontend environment - visible in the browser at given url "/my-image.png"
- in node.js environment - path to file in filesystem
You can add multiple effects to the 'onLayerObject' - in this example it is image.
image1.load("my-image.png", function () {
const obj = layer1.put(image1, 0, 0); // put image1 on the layer with position 0, 0
// edge detection combo
obj.applyEffect("edge");
obj.applyEffect("gray-scale");
obj.applyEffect("invert");
});
Some effects has a parameters, but if you don't pass any then the default parameters will be used.
obj.applyEffect(effectName, {
parameter1: "value1",
parameter2: 255,
});
You can add effect to a whole layer:
image1.load("my-image.png", function () {
const obj = layer1.put(image1, 0, 0); // put image1 on the a layer with position 0, 0
layer1.applyEffect("invert");
});
or whole project:
image1.load("my-image.png", function () {
const obj = layer1.put(image1, 0, 0); // put image1 on the layer with position 0, 0
project.applyEffect("sepia");
});
Layers support alpha compositing and the blending modes. While alpha compositing is internal process and do not require your attention the blending mode you can set by
passing parameters to createLayer
method.
const layer2 = project.createLayer({
blendingMode: "average",
});
- lighten
- darken
- multiply
- average
- add
- subtract
- difference
- negation
- screen
- exclusion
- overlay
- softLight
- hardLight
- colorDodge
- colorBurn
- linearDodge
- linearBurn
- linearLight
- vividLight
- pinLight
- hardMix
- reflect
- glow
- phoenix
image1.load("img/pencils.jpg", function () {
const obj = layer1.put(image1, 0, 0);
obj.crop(100, 100, 100, 100); // startX, startY, width, height
});
image1.load("img/pencils.jpg", function () {
const obj = layer1.put(image1, 200, 150);
obj.resize(200, 150 /*, mode */);
// or
layer1.resize(200, 150 /*, mode */);
// or
project.resize(200, 150);
});
Note that 'obj' and 'layer' resize do not modify Project dimensions. To rescale result image you have to change size o a project.
The following resize modes are supported:
- "nearest-neighbour" - default
- "bilinear-interpolation",
- "biquadratic-interpolation".
- gray-scale
- sepia
- contrast
- brightness
- diffusion
- dither
- exposure
- gain
- gamma
- gray
- hsb-adjust
- invert-alpha
- invert
- rescale
- solarize
- threshold
- tritone
- levels
- diffuse
- kaleidoscope
- pinch
- ripple
- shear
- sphere
- swim
- twirl
- water
- dissolve
- edge
- fill-color
- channel-mix
- circle
- rotate
- flip
- offset
- polar
- block
- border
- emboss
Some effects support parameters. If none passed - the default value will be used.
To use effect params pass it as a second argument:
onLayerObject.applyEffect("edge", { parameter1: "someValue" });
defaults:
defaults: {
contrast: 0 // between -1 and 1
}
defaults:
defaults: {
brightness: 0 // between -1 and 1
}
defaults: {
matrix: [0, 0, 0, 0, 0, 7, 3, 5, 1],
levels: 6,
colorDither: true,
granulate: true
},
defaults: {
matrices: {
ditherMagic4x4Matrix: [
0, 14, 3, 13,
11, 5, 8, 6,
12, 2, 15, 1,
7, 9, 4, 10
],
ditherOrdered4x4Matrix: [
0, 8, 2, 10,
12, 4, 14, 6,
3, 11, 1, 9,
15, 7, 13, 5
],
ditherLines4x4Matrix: [
0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15
],
dither90Halftone6x6Matrix: [
29, 18, 12, 19, 30, 34,
17, 7, 4, 8, 20, 28,
11, 3, 0, 1, 9, 27,
16, 6, 2, 5, 13, 26,
25, 15, 10, 14, 21, 31,
33, 25, 24, 23, 33, 36
],
ditherOrdered6x6Matrix: [
1, 59, 15, 55, 2, 56, 12, 52,
33, 17, 47, 31, 34, 18, 44, 28,
9, 49, 5, 63, 10, 50, 6, 60,
41, 25, 37, 21, 42, 26, 38, 22,
3, 57, 13, 53, 0, 58, 14, 54,
35, 19, 45, 29, 32, 16, 46, 30,
11, 51, 7, 61, 8, 48, 4, 62,
43, 27, 39, 23, 40, 24, 36, 20
],
ditherOrdered8x8Matrix: [
1, 235, 59, 219, 15, 231, 55, 215, 2, 232, 56, 216, 12, 228, 52, 212,
129, 65, 187, 123, 143, 79, 183, 119, 130, 66, 184, 120, 140, 76, 180, 116,
33, 193, 17, 251, 47, 207, 31, 247, 34, 194, 18, 248, 44, 204, 28, 244,
161, 97, 145, 81, 175, 111, 159, 95, 162, 98, 146, 82, 172, 108, 156, 92,
9, 225, 49, 209, 5, 239, 63, 223, 10, 226, 50, 210, 6, 236, 60, 220,
137, 73, 177, 113, 133, 69, 191, 127, 138, 74, 178, 114, 134, 70, 188, 124,
41, 201, 25, 241, 37, 197, 21, 255, 42, 202, 26, 242, 38, 198, 22, 252,
169, 105, 153, 89, 165, 101, 149, 85, 170, 106, 154, 90, 166, 102, 150, 86,
3, 233, 57, 217, 13, 229, 53, 213, 0, 234, 58, 218, 14, 230, 54, 214,
131, 67, 185, 121, 141, 77, 181, 117, 128, 64, 186, 122, 142, 78, 182, 118,
35, 195, 19, 249, 45, 205, 29, 245, 32, 192, 16, 250, 46, 206, 30, 246,
163, 99, 147, 83, 173, 109, 157, 93, 160, 96, 144, 80, 174, 110, 158, 94,
11, 227, 51, 211, 7, 237, 61, 221, 8, 224, 48, 208, 4, 238, 62, 222,
139, 75, 179, 115, 135, 71, 189, 125, 136, 72, 176, 112, 132, 68, 190, 126,
43, 203, 27, 243, 39, 199, 23, 253, 40, 200, 24, 240, 36, 196, 20, 254,
171, 107, 155, 91, 167, 103, 151, 87, 168, 104, 152, 88, 164, 100, 148, 84
],
ditherCluster3Matrix: [
9, 11, 10, 8, 6, 7,
12, 17, 16, 5, 0, 1,
13, 14, 15, 4, 3, 2,
8, 6, 7, 9, 11, 10,
5, 0, 1, 12, 17, 16,
4, 3, 2, 13, 14, 15
],
ditherCluster4Matrix: [
18, 20, 19, 16, 13, 11, 12, 15,
27, 28, 29, 22, 4, 3, 2, 9,
26, 31, 30, 21, 5, 0, 1, 10,
23, 25, 24, 17, 8, 6, 7, 14,
13, 11, 12, 15, 18, 20, 19, 16,
4, 3, 2, 9, 27, 28, 29, 22,
5, 0, 1, 10, 26, 31, 30, 21,
8, 6, 7, 14, 23, 25, 24, 17
],
ditherCluster8Matrix: [
64, 69, 77, 87, 86, 76, 68, 67, 63, 58, 50, 40, 41, 51, 59, 60,
70, 94, 100, 109, 108, 99, 93, 75, 57, 33, 27, 18, 19, 28, 34, 52,
78, 101, 114, 116, 115, 112, 98, 83, 49, 26, 13, 11, 12, 15, 29, 44,
88, 110, 123, 124, 125, 118, 107, 85, 39, 17, 4, 3, 2, 9, 20, 42,
89, 111, 122, 127, 126, 117, 106, 84, 38, 16, 5, 0, 1, 10, 21, 43,
79, 102, 119, 121, 120, 113, 97, 82, 48, 25, 8, 6, 7, 14, 30, 45,
71, 95, 103, 104, 105, 96, 92, 74, 56, 32, 24, 23, 22, 31, 35, 53,
65, 72, 80, 90, 91, 81, 73, 66, 62, 55, 47, 37, 36, 46, 54, 61,
63, 58, 50, 40, 41, 51, 59, 60, 64, 69, 77, 87, 86, 76, 68, 67,
57, 33, 27, 18, 19, 28, 34, 52, 70, 94, 100, 109, 108, 99, 93, 75,
49, 26, 13, 11, 12, 15, 29, 44, 78, 101, 114, 116, 115, 112, 98, 83,
39, 17, 4, 3, 2, 9, 20, 42, 88, 110, 123, 124, 125, 118, 107, 85,
38, 16, 5, 0, 1, 10, 21, 43, 89, 111, 122, 127, 126, 117, 106, 84,
48, 25, 8, 6, 7, 14, 30, 45, 79, 102, 119, 121, 120, 113, 97, 82,
56, 32, 24, 23, 22, 31, 35, 53, 71, 95, 103, 104, 105, 96, 92, 74,
62, 55, 47, 37, 36, 46, 54, 61, 65, 72, 80, 90, 91, 81, 73, 66
]
},
levels: 6,
matrix: "ditherMagic4x4Matrix",
colorDither: true
}
defaults: {
exposure: 1
}
defaults: {
gammaRed: 1,
gammaGreen: 1,
gammaBlue: 1
},
defaults: {
h: 1,
s: 1,
b: 1
}
defaults: {
low: 0,
high: 1,
lowOutput: 0,
highOutput: 1
},
defaults: {
levels: 6
},
defaults: {
matrix: [
0, 0, 0,
0, 0, 7,
3, 5, 1
],
dither: true,
numColors: 256,
serpentine: true
},
defaults: {
scale: 1
}
defaults: {
shadowColor: {
r: 0,
g: 0,
b: 0,
a: 255
},
midColor: {
r: 136,
g: 136,
b: 136,
a: 255
},
highColor: {
r: 255,
g: 255,
b: 255,
a: 255
}
},
defaults: {
scale: 4
},
defaults: {
density: 1,
softness: 0
},
defaults: {
centreX: 0.5,
centreY: 0.5,
angle: 0,
angle2: 0,
sides: 3,
radius: 0
},
defaults: {
angle: 0,
centreX: 0.5,
centreY: 0.5,
radius: 100,
amount: 0.5
},
defaults: {
xAmplitude: 5,
yAmplitute: 0,
xWaveLength: 16,
yWaveLength: 16,
waveType: "SINE" // SAWTOOTH TRIANGLE NOISE
}
defaults: {
xAngle: 0,
yAngle: 0,
xOffset: 0,
yOffset: 0
},
defaults: {
a: 0,
b: 0,
centreX: 0.5,
centreY: 0.5,
refractionIndex: 1.5
},
defaults: {
scale: 32,
turbulence: 0,
amount: 1,
time: 0,
angle: 0,
stretch: 1
},
defaults: {
angle: 0,
centreX: 0.5,
centreY: 0.5,
radius: 100
},
defaults: {
waveLength: 16,
amplitude: 10,
phase: 0,
centreX: 0.5,
centreY: 0.5,
radius: 50
},
defaults: {
matrixes: {
robertsV: [
0, 0, -1,
0, 1, 0,
0, 0, 0
],
robertsH: [
-1, 0, 0,
0, 1, 0,
0, 0, 0
],
prewittV: [
-1, 0, 1,
-1, 0, 1,
-1, 0, 1
],
prewittH: [
-1, -1, -1,
0, 0, 0,
1, 1, 1
],
sobelV: [
-1, 0, 1,
-2, 0, 2,
-1, 0, 1
],
sobelH: [
-1, -2, -1,
0, 0, 0,
1, 2, 1
],
freiChenV: [
-1, 0, 1,
-Math.sqrt(2), 0, Math.sqrt(2),
-1, 0, 1
],
freiChenH: [
-1, -Math.sqrt(2), -1,
0, 0, 0,
1, Math.sqrt(2), 1
]
},
hEdgeMatrix: "sobelV",
vEdgeMatrix: "sobelH"
},
defaults: {
color: "transparent"
}
defaults: {
blueGreen: 1,
redBlue: 1,
greenRed: 1,
intoR: 1,
intoG: 1,
intoB: 1
}
defaults: {
radius: 10,
height: 20,
angle: 0,
spreadAngle: Math.PI,
centreX: 0.5,
centreY: 0.5
},
defaults: {
angle: Math.PI
},
defaults: {
operation: "FLIP_H" // FLIP_H, FLIP_V, FLIP_HV, FLIP_90CW, FLIP_90CCW, FLIP_180
}
defaults: {
xOffset: 100,
yOffset: 100,
wrap: true
},
defaults: {
type: "RECT_TO_POLAR" // RECT_TO_POLAR, POLAR_TO_RECT, INVERT_IN_CIRCLE
},
defaults: {
blockSize: 5
}
defaults: {
leftBorder: 10,
rightBorder: 10,
topBorder: 10,
bottomBorder: 10,
borderColor: {
r: 0,
b: 0,
g: 0,
a: 255
}
},
defaults: {
azimuth: 135 * Math.PI / 180,
elevation: 30 * Math.PI / 180,
width45: 3,
emboss: true
},
defaults: {
x0: 0,
y0: 0,
x1: 1,
y1: 0,
x2: 1,
y2: 1,
x3: 0,
y3: 1
},
To export the Project (result image) you have to call:
project.render(); // returns HTML Image object with src attribute set.
project.save("path/to/file.png");
npm install -g imagizer
imagizer --effect=EnhanceColors --input=demo/test.png --output=demo/bin-output.png --outputImageType=image/png
imagizer --effect=GrayScale --input=demo/test.png --output=demo/bin-output.png --outputImageType=image/png
imagizer --effect=Sepia --sepiaValue=1 --input=demo/test.png --output=demo/bin-output.png --outputImageType=image/png
imagizer --effect=Resize --width=100 --height=100 --input=demo/test.png --output=demo/bin-output.png --outputImageType=image/png