xpict 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dev-scripts/generate-exports.cjs +57 -0
- package/dev-scripts/index.ts +149 -0
- package/dev-scripts/prepare-package-json.js +31 -0
- package/dist/cjs/actions.js +232 -0
- package/dist/cjs/constants.js +26 -0
- package/dist/cjs/index.js +77 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/utils/clone-image.util.ts.js +12 -0
- package/dist/cjs/utils/color.util.js +21 -0
- package/dist/cjs/utils/create-image.util.js +18 -0
- package/dist/cjs/utils/index.js +14 -0
- package/dist/cjs/utils/open-image.util.js +10 -0
- package/dist/esm/actions.js +214 -0
- package/dist/esm/constants.js +20 -0
- package/dist/esm/index.js +71 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/utils/clone-image.util.ts.js +7 -0
- package/dist/esm/utils/color.util.js +17 -0
- package/dist/esm/utils/create-image.util.js +13 -0
- package/dist/esm/utils/index.js +4 -0
- package/dist/esm/utils/open-image.util.js +5 -0
- package/dist/tsconfig.cjs.tsbuildinfo +1 -0
- package/dist/tsconfig.esm.tsbuildinfo +1 -0
- package/dist/tsconfig.types.tsbuildinfo +1 -0
- package/dist/types/actions.d.ts +77 -0
- package/dist/types/constants.d.ts +19 -0
- package/dist/types/index.d.ts +31 -0
- package/dist/types/utils/clone-image.util.ts.d.ts +4 -0
- package/dist/types/utils/color.util.d.ts +4 -0
- package/dist/types/utils/create-image.util.d.ts +12 -0
- package/dist/types/utils/index.d.ts +4 -0
- package/dist/types/utils/open-image.util.d.ts +3 -0
- package/fonts/Curse Casual.ttf +0 -0
- package/fonts/Poppins-Black.ttf +0 -0
- package/fonts/Poppins-BlackItalic.ttf +0 -0
- package/fonts/Poppins-Bold.ttf +0 -0
- package/fonts/Poppins-BoldItalic.ttf +0 -0
- package/fonts/Poppins-ExtraBold.ttf +0 -0
- package/fonts/Poppins-ExtraBoldItalic.ttf +0 -0
- package/fonts/Poppins-ExtraLight.ttf +0 -0
- package/fonts/Poppins-ExtraLightItalic.ttf +0 -0
- package/fonts/Poppins-Italic.ttf +0 -0
- package/fonts/Poppins-Light.ttf +0 -0
- package/fonts/Poppins-LightItalic.ttf +0 -0
- package/fonts/Poppins-Medium.ttf +0 -0
- package/fonts/Poppins-MediumItalic.ttf +0 -0
- package/fonts/Poppins-Regular.ttf +0 -0
- package/fonts/Poppins-SemiBold.ttf +0 -0
- package/fonts/Poppins-SemiBoldItalic.ttf +0 -0
- package/fonts/Poppins-Thin.ttf +0 -0
- package/fonts/Poppins-ThinItalic.ttf +0 -0
- package/package.json +78 -0
- package/src/actions.ts +390 -0
- package/src/constants.ts +30 -0
- package/src/index.ts +124 -0
- package/src/utils/clone-image.util.ts.ts +11 -0
- package/src/utils/color.util.ts +25 -0
- package/src/utils/create-image.util.ts +34 -0
- package/src/utils/index.ts +11 -0
- package/src/utils/open-image.util.ts +9 -0
- package/tsconfig.cjs.json +7 -0
- package/tsconfig.esm.json +7 -0
- package/tsconfig.json +15 -0
- package/tsconfig.types.json +8 -0
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { createCanvas, registerFont } from "canvas";
|
|
2
|
+
import { colors, insertTextDefaultOptions } from "./constants";
|
|
3
|
+
function toGrayScale(grayscale = true) {
|
|
4
|
+
return (image) => image.grayscale(grayscale);
|
|
5
|
+
}
|
|
6
|
+
function cropImage(options) {
|
|
7
|
+
return (image) => image.extract(options);
|
|
8
|
+
}
|
|
9
|
+
function resizeImage({ width, height, fit = "inside" }) {
|
|
10
|
+
return (image) => image.resize(width, height, { fit: fit });
|
|
11
|
+
}
|
|
12
|
+
function rotateImage(angle) {
|
|
13
|
+
return (image) => image.rotate(angle);
|
|
14
|
+
}
|
|
15
|
+
function blurImage(sigma = 1) {
|
|
16
|
+
return (image) => image.blur(sigma);
|
|
17
|
+
}
|
|
18
|
+
function modulateSaturation(saturation) {
|
|
19
|
+
return (image) => image.modulate({ saturation });
|
|
20
|
+
}
|
|
21
|
+
function modulateBrightness(brightness) {
|
|
22
|
+
return (image) => image.modulate({ brightness });
|
|
23
|
+
}
|
|
24
|
+
function invertColors() {
|
|
25
|
+
return (image) => image.negate();
|
|
26
|
+
}
|
|
27
|
+
function addBorder({ size, color = colors.black }) {
|
|
28
|
+
return (image) => image.extend({
|
|
29
|
+
top: size,
|
|
30
|
+
bottom: size,
|
|
31
|
+
left: size,
|
|
32
|
+
right: size,
|
|
33
|
+
background: color
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function adjustContrast(contrast) {
|
|
37
|
+
return (image) => {
|
|
38
|
+
const factor = (259 * (contrast + 255)) / (255 * (259 - contrast));
|
|
39
|
+
return image.linear(factor, -(128 * factor) + 128);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function modulateOpacity(opacity) {
|
|
43
|
+
return (image) => image.flatten({ background: { alpha: opacity } });
|
|
44
|
+
}
|
|
45
|
+
function flipImage() {
|
|
46
|
+
return (image) => image.flip();
|
|
47
|
+
}
|
|
48
|
+
function flopImage() {
|
|
49
|
+
return (image) => image.flop();
|
|
50
|
+
}
|
|
51
|
+
function insertText({ text, font, x, y, backgroundColor = insertTextDefaultOptions.backgroundColor, anchor = insertTextDefaultOptions.anchor, stroke, rotation = insertTextDefaultOptions.rotation }) {
|
|
52
|
+
return async (image) => {
|
|
53
|
+
const imageMetadata = await image.metadata();
|
|
54
|
+
const width = imageMetadata.width;
|
|
55
|
+
const height = imageMetadata.height;
|
|
56
|
+
const canvas = createCanvas(width, height);
|
|
57
|
+
const context = canvas.getContext("2d");
|
|
58
|
+
if (backgroundColor !== "transparent") {
|
|
59
|
+
context.fillStyle = backgroundColor;
|
|
60
|
+
context.fillRect(0, 0, width, height);
|
|
61
|
+
}
|
|
62
|
+
if (font.filePath) {
|
|
63
|
+
registerFont(font.filePath, { family: font.name });
|
|
64
|
+
}
|
|
65
|
+
context.font = `${font.size}px ${font.name ?? insertTextDefaultOptions.font.name}`;
|
|
66
|
+
context.fillStyle = font.color ?? colors.black;
|
|
67
|
+
const textMetrics = context.measureText(text);
|
|
68
|
+
const textWidth = textMetrics.width;
|
|
69
|
+
const textHeight = font.size;
|
|
70
|
+
const anchorOffsets = {
|
|
71
|
+
"top-left": {
|
|
72
|
+
x: 0,
|
|
73
|
+
y: 0
|
|
74
|
+
},
|
|
75
|
+
"top-center": {
|
|
76
|
+
x: -textWidth / 2,
|
|
77
|
+
y: 0
|
|
78
|
+
},
|
|
79
|
+
"top-right": {
|
|
80
|
+
x: -textWidth,
|
|
81
|
+
y: 0
|
|
82
|
+
},
|
|
83
|
+
"middle-left": {
|
|
84
|
+
x: 0,
|
|
85
|
+
y: -textHeight / 2
|
|
86
|
+
},
|
|
87
|
+
"middle-center": {
|
|
88
|
+
x: -textWidth / 2,
|
|
89
|
+
y: -textHeight / 2
|
|
90
|
+
},
|
|
91
|
+
"middle-right": {
|
|
92
|
+
x: -textWidth,
|
|
93
|
+
y: -textHeight / 2
|
|
94
|
+
},
|
|
95
|
+
"bottom-left": {
|
|
96
|
+
x: 0,
|
|
97
|
+
y: -textHeight
|
|
98
|
+
},
|
|
99
|
+
"bottom-center": {
|
|
100
|
+
x: -textWidth / 2,
|
|
101
|
+
y: -textHeight
|
|
102
|
+
},
|
|
103
|
+
"bottom-right": {
|
|
104
|
+
x: -textWidth,
|
|
105
|
+
y: -textHeight
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
const { x: offsetX, y: offsetY } = anchorOffsets[anchor] || { x: 0, y: 0 };
|
|
109
|
+
const adjustedX = x + offsetX;
|
|
110
|
+
const adjustedY = y + offsetY;
|
|
111
|
+
const adjustedRotation = rotation ?? 0;
|
|
112
|
+
context.save();
|
|
113
|
+
context.translate(adjustedX, adjustedY);
|
|
114
|
+
context.rotate((adjustedRotation * Math.PI) / 180);
|
|
115
|
+
if (stroke) {
|
|
116
|
+
context.strokeStyle = stroke.fill;
|
|
117
|
+
context.lineWidth = stroke.width;
|
|
118
|
+
context.lineJoin = "round";
|
|
119
|
+
context.strokeText(text, 0, 0);
|
|
120
|
+
}
|
|
121
|
+
context.fillStyle = font.color ?? colors.black;
|
|
122
|
+
context.fillText(text, 0, 0);
|
|
123
|
+
context.restore();
|
|
124
|
+
const textBuffer = canvas.toBuffer();
|
|
125
|
+
return image.composite([
|
|
126
|
+
{
|
|
127
|
+
input: textBuffer,
|
|
128
|
+
top: 0,
|
|
129
|
+
left: 0
|
|
130
|
+
}
|
|
131
|
+
]);
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function insertCircle({ x, y, radius, fill }) {
|
|
135
|
+
return async (image) => {
|
|
136
|
+
const imageMetadata = await image.metadata();
|
|
137
|
+
const width = imageMetadata.width;
|
|
138
|
+
const height = imageMetadata.height;
|
|
139
|
+
const canvas = createCanvas(width, height);
|
|
140
|
+
const context = canvas.getContext("2d");
|
|
141
|
+
context.beginPath();
|
|
142
|
+
context.arc(x, y, radius, 0, Math.PI * 2, true);
|
|
143
|
+
context.closePath();
|
|
144
|
+
context.fillStyle = fill;
|
|
145
|
+
context.fill();
|
|
146
|
+
const circleBuffer = canvas.toBuffer();
|
|
147
|
+
return image.composite([
|
|
148
|
+
{
|
|
149
|
+
input: circleBuffer,
|
|
150
|
+
top: 0,
|
|
151
|
+
left: 0
|
|
152
|
+
}
|
|
153
|
+
]);
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function insertRectangle({ x, y, width, height, fill, borderRadius }) {
|
|
157
|
+
return async (image) => {
|
|
158
|
+
const imageMetadata = await image.metadata();
|
|
159
|
+
const canvasWidth = imageMetadata.width;
|
|
160
|
+
const canvasHeight = imageMetadata.height;
|
|
161
|
+
const canvas = createCanvas(canvasWidth, canvasHeight);
|
|
162
|
+
const context = canvas.getContext("2d");
|
|
163
|
+
context.fillStyle = fill;
|
|
164
|
+
if (borderRadius && borderRadius > 0) {
|
|
165
|
+
context.beginPath();
|
|
166
|
+
context.moveTo(x + borderRadius, y);
|
|
167
|
+
context.lineTo(x + width - borderRadius, y);
|
|
168
|
+
context.arcTo(x + width, y, x + width, y + height, borderRadius);
|
|
169
|
+
context.lineTo(x + width, y + height - borderRadius);
|
|
170
|
+
context.arcTo(x + width, y + height, x, y + height, borderRadius);
|
|
171
|
+
context.lineTo(x + borderRadius, y + height);
|
|
172
|
+
context.arcTo(x, y + height, x, y, borderRadius);
|
|
173
|
+
context.lineTo(x, y + borderRadius);
|
|
174
|
+
context.arcTo(x, y, x + width, y, borderRadius);
|
|
175
|
+
context.closePath();
|
|
176
|
+
context.fill();
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
context.fillRect(x, y, width, height);
|
|
180
|
+
}
|
|
181
|
+
const rectangleBuffer = canvas.toBuffer();
|
|
182
|
+
return image.composite([
|
|
183
|
+
{
|
|
184
|
+
input: rectangleBuffer,
|
|
185
|
+
top: 0,
|
|
186
|
+
left: 0
|
|
187
|
+
}
|
|
188
|
+
]);
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
function insertLine({ x1, y1, x2, y2, color, width }) {
|
|
192
|
+
return async (image) => {
|
|
193
|
+
const imageMetadata = await image.metadata();
|
|
194
|
+
const canvasWidth = imageMetadata.width;
|
|
195
|
+
const canvasHeight = imageMetadata.height;
|
|
196
|
+
const canvas = createCanvas(canvasWidth, canvasHeight);
|
|
197
|
+
const context = canvas.getContext("2d");
|
|
198
|
+
context.strokeStyle = color;
|
|
199
|
+
context.lineWidth = width;
|
|
200
|
+
context.beginPath();
|
|
201
|
+
context.moveTo(x1, y1);
|
|
202
|
+
context.lineTo(x2, y2);
|
|
203
|
+
context.stroke();
|
|
204
|
+
const lineBuffer = canvas.toBuffer();
|
|
205
|
+
return image.composite([
|
|
206
|
+
{
|
|
207
|
+
input: lineBuffer,
|
|
208
|
+
top: 0,
|
|
209
|
+
left: 0
|
|
210
|
+
}
|
|
211
|
+
]);
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
export { toGrayScale, cropImage, resizeImage, rotateImage, blurImage, modulateSaturation, modulateBrightness, invertColors, addBorder, adjustContrast, modulateOpacity, flipImage, flopImage, insertText, insertCircle, insertRectangle, insertLine };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { rgba } from "./utils/color.util";
|
|
2
|
+
const colors = {
|
|
3
|
+
black: "#000000",
|
|
4
|
+
white: "#FFFFFF"
|
|
5
|
+
};
|
|
6
|
+
const defautltTemplateAcitonType = "beforeLayersProccess";
|
|
7
|
+
const createImageDefaultOptions = {
|
|
8
|
+
chnannels: 4,
|
|
9
|
+
fill: rgba(0, 0, 0, 0),
|
|
10
|
+
format: "png"
|
|
11
|
+
};
|
|
12
|
+
const insertTextDefaultOptions = {
|
|
13
|
+
font: {
|
|
14
|
+
name: "sans-serif",
|
|
15
|
+
},
|
|
16
|
+
anchor: "top-left",
|
|
17
|
+
backgroundColor: "transparent",
|
|
18
|
+
rotation: 0
|
|
19
|
+
};
|
|
20
|
+
export { colors, defautltTemplateAcitonType, createImageDefaultOptions, insertTextDefaultOptions };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { defautltTemplateAcitonType } from "./constants";
|
|
2
|
+
import cloneImage from "./utils/clone-image.util.ts";
|
|
3
|
+
function extractActions(actions) {
|
|
4
|
+
const actionsLayersProccess = [];
|
|
5
|
+
const actionsAfterLayersProccess = [];
|
|
6
|
+
if (!actions) {
|
|
7
|
+
actions = [];
|
|
8
|
+
}
|
|
9
|
+
for (const action of actions) {
|
|
10
|
+
const actionType = typeof action === "function" ? defautltTemplateAcitonType : action.type;
|
|
11
|
+
const actionFunc = typeof action === "function" ? action : action.func;
|
|
12
|
+
if (actionType === "beforeLayersProccess") {
|
|
13
|
+
actionsLayersProccess.push(actionFunc);
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
actionsAfterLayersProccess.push(actionFunc);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
before: actionsLayersProccess,
|
|
21
|
+
after: actionsAfterLayersProccess
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
async function processImageTemplate(template) {
|
|
25
|
+
const actions = extractActions(template.actions);
|
|
26
|
+
let image = template.image;
|
|
27
|
+
for (const action of actions.before) {
|
|
28
|
+
const imageResult = await action(image);
|
|
29
|
+
image = await cloneImage(imageResult);
|
|
30
|
+
}
|
|
31
|
+
if (template.layers) {
|
|
32
|
+
const layerImages = [];
|
|
33
|
+
for (const layer of template.layers) {
|
|
34
|
+
const currentImage = await processImageTemplate(layer.template);
|
|
35
|
+
const currentImageBuffer = await currentImage.png().toBuffer();
|
|
36
|
+
layerImages.push({
|
|
37
|
+
input: currentImageBuffer,
|
|
38
|
+
top: layer.y,
|
|
39
|
+
left: layer.x
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
image = image.composite(layerImages);
|
|
43
|
+
}
|
|
44
|
+
for (const action of actions.after) {
|
|
45
|
+
const imageResult = await action(image);
|
|
46
|
+
image = await cloneImage(imageResult);
|
|
47
|
+
}
|
|
48
|
+
return image;
|
|
49
|
+
}
|
|
50
|
+
function extendImageTemplate(template, extendTemplate) {
|
|
51
|
+
const actions = [];
|
|
52
|
+
const layers = [];
|
|
53
|
+
if (template.layers) {
|
|
54
|
+
layers.push(...template.layers);
|
|
55
|
+
}
|
|
56
|
+
if (extendTemplate.layers) {
|
|
57
|
+
layers.push(...extendTemplate.layers);
|
|
58
|
+
}
|
|
59
|
+
if (template.actions) {
|
|
60
|
+
actions.push(...template.actions);
|
|
61
|
+
}
|
|
62
|
+
if (extendTemplate.actions) {
|
|
63
|
+
actions.push(...extendTemplate.actions);
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
image: template.image,
|
|
67
|
+
actions: actions,
|
|
68
|
+
layers: layers
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export { processImageTemplate, extendImageTemplate };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type": "module"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
function componentToHex(component) {
|
|
2
|
+
const hex = component.toString(16);
|
|
3
|
+
return hex.padStart(2, "0");
|
|
4
|
+
}
|
|
5
|
+
function rgb(red, green, blue) {
|
|
6
|
+
return `#${componentToHex(red)}${componentToHex(green)}${componentToHex(blue)}`;
|
|
7
|
+
}
|
|
8
|
+
function rgba(red, green, blue, alpha) {
|
|
9
|
+
const alphaHex = componentToHex(Math.round(alpha * 255));
|
|
10
|
+
return `#${componentToHex(red)}${componentToHex(green)}${componentToHex(blue)}${alphaHex}`;
|
|
11
|
+
}
|
|
12
|
+
function hex(value) {
|
|
13
|
+
const hexadecimalValue = value.toString(16);
|
|
14
|
+
const fromatedHexadecimal = `#${hexadecimalValue.padStart(6, "0")}`;
|
|
15
|
+
return fromatedHexadecimal;
|
|
16
|
+
}
|
|
17
|
+
export { rgb, rgba, hex };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import sharp from "sharp";
|
|
2
|
+
import { createImageDefaultOptions } from "../constants";
|
|
3
|
+
function createImage({ width, height, fill = createImageDefaultOptions.fill, channels = createImageDefaultOptions.chnannels, format = createImageDefaultOptions.format, }) {
|
|
4
|
+
return sharp({
|
|
5
|
+
create: {
|
|
6
|
+
width: width,
|
|
7
|
+
height: height,
|
|
8
|
+
channels: channels,
|
|
9
|
+
background: fill,
|
|
10
|
+
},
|
|
11
|
+
})[format]();
|
|
12
|
+
}
|
|
13
|
+
export default createImage;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["../src/actions.ts","../src/constants.ts","../src/index.ts","../src/utils/clone-image.util.ts.ts","../src/utils/color.util.ts","../src/utils/create-image.util.ts","../src/utils/index.ts","../src/utils/open-image.util.ts"],"version":"5.6.2"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["../src/actions.ts","../src/constants.ts","../src/index.ts","../src/utils/clone-image.util.ts.ts","../src/utils/color.util.ts","../src/utils/create-image.util.ts","../src/utils/index.ts","../src/utils/open-image.util.ts"],"version":"5.6.2"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["../src/actions.ts","../src/constants.ts","../src/index.ts","../src/utils/clone-image.util.ts.ts","../src/utils/color.util.ts","../src/utils/create-image.util.ts","../src/utils/index.ts","../src/utils/open-image.util.ts"],"version":"5.6.2"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import sharp from "sharp";
|
|
2
|
+
import { Image } from ".";
|
|
3
|
+
declare function toGrayScale(grayscale?: boolean): (image: Image) => sharp.Sharp;
|
|
4
|
+
export type CropImageOptions = sharp.Region;
|
|
5
|
+
declare function cropImage(options: CropImageOptions): (image: Image) => sharp.Sharp;
|
|
6
|
+
export type ResizeImageOptions = {
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
fit: keyof sharp.FitEnum;
|
|
10
|
+
};
|
|
11
|
+
declare function resizeImage({ width, height, fit }: ResizeImageOptions): (image: Image) => sharp.Sharp;
|
|
12
|
+
declare function rotateImage(angle: number): (image: Image) => sharp.Sharp;
|
|
13
|
+
declare function blurImage(sigma?: number): (image: Image) => sharp.Sharp;
|
|
14
|
+
declare function modulateSaturation(saturation: number): (image: Image) => sharp.Sharp;
|
|
15
|
+
declare function modulateBrightness(brightness: number): (image: Image) => sharp.Sharp;
|
|
16
|
+
declare function invertColors(): (image: Image) => sharp.Sharp;
|
|
17
|
+
export type AddBorderOptions = {
|
|
18
|
+
size: number;
|
|
19
|
+
color?: string;
|
|
20
|
+
};
|
|
21
|
+
declare function addBorder({ size, color }: AddBorderOptions): (image: Image) => sharp.Sharp;
|
|
22
|
+
declare function adjustContrast(contrast: number): (image: Image) => sharp.Sharp;
|
|
23
|
+
declare function modulateOpacity(opacity: number): (image: Image) => sharp.Sharp;
|
|
24
|
+
declare function flipImage(): (image: Image) => sharp.Sharp;
|
|
25
|
+
declare function flopImage(): (image: Image) => sharp.Sharp;
|
|
26
|
+
export type FontOptions = {
|
|
27
|
+
size: number;
|
|
28
|
+
color?: string;
|
|
29
|
+
name?: string;
|
|
30
|
+
filePath?: string;
|
|
31
|
+
};
|
|
32
|
+
export type TextAnchor = "top-left" | "top-center" | "top-right" | "middle-left" | "middle-center" | "middle-right" | "bottom-left" | "bottom-center" | "bottom-right";
|
|
33
|
+
export type Stroke = {
|
|
34
|
+
fill: string;
|
|
35
|
+
width: number;
|
|
36
|
+
};
|
|
37
|
+
export type InsertTextOptions = {
|
|
38
|
+
text: string;
|
|
39
|
+
font: FontOptions;
|
|
40
|
+
x: number;
|
|
41
|
+
y: number;
|
|
42
|
+
backgroundColor?: string;
|
|
43
|
+
anchor?: TextAnchor;
|
|
44
|
+
stroke?: Stroke;
|
|
45
|
+
rotation?: number;
|
|
46
|
+
};
|
|
47
|
+
export type AnchorOffsets = Record<TextAnchor, {
|
|
48
|
+
x: number;
|
|
49
|
+
y: number;
|
|
50
|
+
}>;
|
|
51
|
+
declare function insertText({ text, font, x, y, backgroundColor, anchor, stroke, rotation }: InsertTextOptions): (image: Image) => Promise<sharp.Sharp>;
|
|
52
|
+
export type InsertCircleOptions = {
|
|
53
|
+
x: number;
|
|
54
|
+
y: number;
|
|
55
|
+
radius: number;
|
|
56
|
+
fill: string;
|
|
57
|
+
};
|
|
58
|
+
declare function insertCircle({ x, y, radius, fill }: InsertCircleOptions): (image: Image) => Promise<sharp.Sharp>;
|
|
59
|
+
export type InsertRectangleOptions = {
|
|
60
|
+
x: number;
|
|
61
|
+
y: number;
|
|
62
|
+
width: number;
|
|
63
|
+
height: number;
|
|
64
|
+
fill: string;
|
|
65
|
+
borderRadius?: number;
|
|
66
|
+
};
|
|
67
|
+
declare function insertRectangle({ x, y, width, height, fill, borderRadius }: InsertRectangleOptions): (image: Image) => Promise<sharp.Sharp>;
|
|
68
|
+
export type InsertLineOptions = {
|
|
69
|
+
x1: number;
|
|
70
|
+
y1: number;
|
|
71
|
+
x2: number;
|
|
72
|
+
y2: number;
|
|
73
|
+
color: string;
|
|
74
|
+
width: number;
|
|
75
|
+
};
|
|
76
|
+
declare function insertLine({ x1, y1, x2, y2, color, width }: InsertLineOptions): (image: Image) => Promise<sharp.Sharp>;
|
|
77
|
+
export { toGrayScale, cropImage, resizeImage, rotateImage, blurImage, modulateSaturation, modulateBrightness, invertColors, addBorder, adjustContrast, modulateOpacity, flipImage, flopImage, insertText, insertCircle, insertRectangle, insertLine };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
declare const colors: {
|
|
2
|
+
black: string;
|
|
3
|
+
white: string;
|
|
4
|
+
};
|
|
5
|
+
declare const defautltTemplateAcitonType = "beforeLayersProccess";
|
|
6
|
+
declare const createImageDefaultOptions: {
|
|
7
|
+
chnannels: number;
|
|
8
|
+
fill: string;
|
|
9
|
+
format: string;
|
|
10
|
+
};
|
|
11
|
+
declare const insertTextDefaultOptions: {
|
|
12
|
+
font: {
|
|
13
|
+
name: string;
|
|
14
|
+
};
|
|
15
|
+
anchor: string;
|
|
16
|
+
backgroundColor: string;
|
|
17
|
+
rotation: number;
|
|
18
|
+
};
|
|
19
|
+
export { colors, defautltTemplateAcitonType, createImageDefaultOptions, insertTextDefaultOptions };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import sharp, { Sharp } from "sharp";
|
|
2
|
+
export type Image = Sharp;
|
|
3
|
+
export type ImageTemplateLayer = {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
template: ImageTemplate;
|
|
7
|
+
};
|
|
8
|
+
export type ImageTemplateActionFunction = (image: Image) => Image | Promise<Image>;
|
|
9
|
+
export type ImageTemplateAction = ImageTemplateActionFunction | {
|
|
10
|
+
type: "beforeLayersProccess" | "afterLayersProccess";
|
|
11
|
+
func: ImageTemplateActionFunction;
|
|
12
|
+
};
|
|
13
|
+
export type ImageTemplate = {
|
|
14
|
+
image: Image;
|
|
15
|
+
actions?: ImageTemplateAction[];
|
|
16
|
+
layers?: ImageTemplateLayer[];
|
|
17
|
+
};
|
|
18
|
+
export type ExtractActionsResult = {
|
|
19
|
+
before: ImageTemplateActionFunction[];
|
|
20
|
+
after: ImageTemplateActionFunction[];
|
|
21
|
+
};
|
|
22
|
+
declare function processImageTemplate(template: ImageTemplate): Promise<Image>;
|
|
23
|
+
declare function extendImageTemplate(template: ImageTemplate, extendTemplate: Omit<ImageTemplate, "image">): {
|
|
24
|
+
image: sharp.Sharp;
|
|
25
|
+
actions: (ImageTemplateActionFunction | {
|
|
26
|
+
type: "beforeLayersProccess" | "afterLayersProccess";
|
|
27
|
+
func: ImageTemplateActionFunction;
|
|
28
|
+
})[];
|
|
29
|
+
layers: ImageTemplateLayer[];
|
|
30
|
+
};
|
|
31
|
+
export { processImageTemplate, extendImageTemplate };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import sharp from "sharp";
|
|
2
|
+
export type ImageChannels = 3 | 4;
|
|
3
|
+
export type ImageFormat = "png" | "jpeg" | "webp" | "avif" | "gif";
|
|
4
|
+
export type CreateImageOptions = {
|
|
5
|
+
width: number;
|
|
6
|
+
height: number;
|
|
7
|
+
fill?: sharp.Color;
|
|
8
|
+
channels?: ImageChannels;
|
|
9
|
+
format?: ImageFormat;
|
|
10
|
+
};
|
|
11
|
+
declare function createImage({ width, height, fill, channels, format, }: CreateImageOptions): sharp.Sharp;
|
|
12
|
+
export default createImage;
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "xpict",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "ts-node ./tests/index.ts",
|
|
8
|
+
"test:hr": "ts-node ./tests/generate-hr-maps.ts",
|
|
9
|
+
"build:clean": "rimraf dist",
|
|
10
|
+
"compile": "tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json ./tsconfig.types.json",
|
|
11
|
+
"build": "npm-run-all build:clean compile generate-exports && node ./dev-scripts/prepare-package-json.js",
|
|
12
|
+
"generate-exports": "node dev-scripts/generate-exports.cjs"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [],
|
|
15
|
+
"author": "Marcuth",
|
|
16
|
+
"license": "ISC",
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@types/node": "^22.5.4",
|
|
19
|
+
"canvas": "^2.11.2",
|
|
20
|
+
"sharp": "^0.33.5",
|
|
21
|
+
"ts-node": "^10.9.2",
|
|
22
|
+
"typescript": "^5.6.2"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"npm-run-all": "^4.1.5",
|
|
26
|
+
"rimraf": "^6.0.1"
|
|
27
|
+
},
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"import": "./dist/index.js",
|
|
31
|
+
"require": "./dist/index.js",
|
|
32
|
+
"default": "./dist/index.js",
|
|
33
|
+
"types": "./dist/index.d.ts"
|
|
34
|
+
},
|
|
35
|
+
"./actions": {
|
|
36
|
+
"import": "./dist/esm/actions.js",
|
|
37
|
+
"require": "./dist/cjs/actions.js",
|
|
38
|
+
"default": "./dist/esm/actions.js",
|
|
39
|
+
"types": "./dist/types/actions.d.ts"
|
|
40
|
+
},
|
|
41
|
+
"./constants": {
|
|
42
|
+
"import": "./dist/esm/constants.js",
|
|
43
|
+
"require": "./dist/cjs/constants.js",
|
|
44
|
+
"default": "./dist/esm/constants.js",
|
|
45
|
+
"types": "./dist/types/constants.d.ts"
|
|
46
|
+
},
|
|
47
|
+
"./utils/clone-image.util.ts": {
|
|
48
|
+
"import": "./dist/esm/utils/clone-image.util.ts.js",
|
|
49
|
+
"require": "./dist/cjs/utils/clone-image.util.ts.js",
|
|
50
|
+
"default": "./dist/esm/utils/clone-image.util.ts.js",
|
|
51
|
+
"types": "./dist/types/utils/clone-image.util.ts.d.ts"
|
|
52
|
+
},
|
|
53
|
+
"./utils/color.util": {
|
|
54
|
+
"import": "./dist/esm/utils/color.util.js",
|
|
55
|
+
"require": "./dist/cjs/utils/color.util.js",
|
|
56
|
+
"default": "./dist/esm/utils/color.util.js",
|
|
57
|
+
"types": "./dist/types/utils/color.util.d.ts"
|
|
58
|
+
},
|
|
59
|
+
"./utils/create-image.util": {
|
|
60
|
+
"import": "./dist/esm/utils/create-image.util.js",
|
|
61
|
+
"require": "./dist/cjs/utils/create-image.util.js",
|
|
62
|
+
"default": "./dist/esm/utils/create-image.util.js",
|
|
63
|
+
"types": "./dist/types/utils/create-image.util.d.ts"
|
|
64
|
+
},
|
|
65
|
+
"./utils": {
|
|
66
|
+
"import": "./dist/esm/utils/index.js",
|
|
67
|
+
"require": "./dist/cjs/utils/index.js",
|
|
68
|
+
"default": "./dist/esm/utils/index.js",
|
|
69
|
+
"types": "./dist/types/utils/index.d.ts"
|
|
70
|
+
},
|
|
71
|
+
"./utils/open-image.util": {
|
|
72
|
+
"import": "./dist/esm/utils/open-image.util.js",
|
|
73
|
+
"require": "./dist/cjs/utils/open-image.util.js",
|
|
74
|
+
"default": "./dist/esm/utils/open-image.util.js",
|
|
75
|
+
"types": "./dist/types/utils/open-image.util.d.ts"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|