apexify.js 1.2.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 +1117 -0
- package/index.js +111 -0
- package/lib/ai/apexAI.js +312 -0
- package/lib/ai/functions/chunkString.js +8 -0
- package/lib/ai/functions/draw.js +347 -0
- package/lib/ai/functions/generateVoiceResponse.js +239 -0
- package/lib/ai/functions/processImageAttachments.js +93 -0
- package/lib/ai/functions/processMessageContent.js +48 -0
- package/lib/ai/functions/readFiles.js +95 -0
- package/lib/ai/functions/shouldDrawImage.js +12 -0
- package/lib/ai/utils.js +18 -0
- package/lib/canvas/ApexPainter.js +1194 -0
- package/lib/canvas/themes/level ara.ttf +0 -0
- package/lib/canvas/themes/levelFont.ttf +0 -0
- package/lib/canvas/themes/levels-card.js +872 -0
- package/lib/canvas/themes/music-card.js +342 -0
- package/lib/canvas/themes/numbers.ttf +0 -0
- package/lib/canvas/themes/tajawal.ttf +0 -0
- package/lib/database/MongoDB.js +126 -0
- package/lib/database/NanoDB.js +1318 -0
- package/lib/database/mongoDb/aggregate.js +120 -0
- package/lib/database/mongoDb/countDocs.js +115 -0
- package/lib/database/mongoDb/createCollection.js +125 -0
- package/lib/database/mongoDb/dataSize.js +89 -0
- package/lib/database/mongoDb/distinct.js +110 -0
- package/lib/database/mongoDb/drop.js +76 -0
- package/lib/database/mongoDb/find.js +122 -0
- package/lib/database/mongoDb/geoNear.js +91 -0
- package/lib/database/mongoDb/index.js +71 -0
- package/lib/database/mongoDb/listCollections.js +81 -0
- package/lib/database/mongoDb/migrateAndPrune.js +89 -0
- package/lib/database/mongoDb/migrateData.js +79 -0
- package/lib/database/mongoDb/remove.js +73 -0
- package/lib/database/mongoDb/removeMany.js +73 -0
- package/lib/database/mongoDb/removeManyExcept.js +91 -0
- package/lib/database/mongoDb/removeSpecific.js +93 -0
- package/lib/database/mongoDb/save.js +94 -0
- package/lib/database/mongoDb/searchMany.js +109 -0
- package/lib/database/mongoDb/textSearch.js +88 -0
- package/lib/database/mongoDb/updateAll.js +80 -0
- package/lib/database/mongoDb/updateAllExcept.js +108 -0
- package/lib/database/mongoDb/updateData.js +106 -0
- package/lib/database/nanoDb/fetchData.js +39 -0
- package/lib/database/nanoDb/removeField.js +46 -0
- package/lib/database/nanoDb/saveData.js +68 -0
- package/lib/database/nanoDb/updateFilter.js +24 -0
- package/lib/database/ready-schemas.js +245 -0
- package/lib/database/utils.js +58 -0
- package/lib/discord/discord-build/commands-(prefix)/music/functions/buttons.js +361 -0
- package/lib/discord/discord-build/commands-(prefix)/music/functions/end.js +58 -0
- package/lib/discord/discord-build/commands-(prefix)/music/functions/start.js +115 -0
- package/lib/discord/discord-build/commands-(prefix)/music/play.js +152 -0
- package/lib/discord/discord-build/commands-(prefix)/music/previous.js +82 -0
- package/lib/discord/discord-build/commands-(prefix)/music/resume.js +93 -0
- package/lib/discord/discord-build/commands-(prefix)/music/skip.js +82 -0
- package/lib/discord/discord-build/commands-(prefix)/music/stop.js +79 -0
- package/lib/discord/discord-build/components/buttons.js +75 -0
- package/lib/discord/discord-build/components/menus.js +81 -0
- package/lib/discord/discord-build/components/paginator.js +156 -0
- package/lib/discord/discord-build/components/permsChecker.js +81 -0
- package/lib/discord/discord-build/utils.js +21 -0
- package/lib/discord/events/eventer.js +100 -0
- package/lib/discord/events/handler/drawMenu.js +351 -0
- package/lib/discord/events/handler/tools.js +652 -0
- package/lib/discord/events/prefixRegister.js +136 -0
- package/lib/discord/events/prefixResponder.js +163 -0
- package/lib/discord/events/slashRegister.js +199 -0
- package/lib/discord/events/slashResponder.js +108 -0
- package/lib/discord/events/starter.js +335 -0
- package/lib/discord/functions/perms.js +19 -0
- package/lib/discord/utils.js +6 -0
- package/lib/general-functions/discord/type-writer.js +77 -0
- package/lib/general-functions/utils.js +0 -0
- package/lib/utils.js +90 -0
- package/package.json +118 -0
|
@@ -0,0 +1,1194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
16
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
17
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
18
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
19
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
23
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
24
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
25
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
26
|
+
function step(op) {
|
|
27
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
28
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
29
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
30
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
31
|
+
switch (op[0]) {
|
|
32
|
+
case 0: case 1: t = op; break;
|
|
33
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
34
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
35
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
36
|
+
default:
|
|
37
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
38
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
39
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
40
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
41
|
+
if (t[2]) _.ops.pop();
|
|
42
|
+
_.trys.pop(); continue;
|
|
43
|
+
}
|
|
44
|
+
op = body.call(thisArg, _);
|
|
45
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
46
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.ApexPainter = void 0;
|
|
51
|
+
var canvas_1 = require("@napi-rs/canvas");
|
|
52
|
+
var path_1 = require("path");
|
|
53
|
+
var axios_1 = require("axios");
|
|
54
|
+
var sharp_1 = require("sharp");
|
|
55
|
+
var fs_1 = require("fs");
|
|
56
|
+
var jimp_1 = require("jimp");
|
|
57
|
+
var form_data_1 = require("form-data");
|
|
58
|
+
var gifencoder_1 = require("gifencoder");
|
|
59
|
+
var stream_1 = require("stream");
|
|
60
|
+
var ApexPainter = /** @class */ (function () {
|
|
61
|
+
function ApexPainter() {
|
|
62
|
+
this.defaultTextOptions = {
|
|
63
|
+
text: "Add Text Here",
|
|
64
|
+
x: 50,
|
|
65
|
+
y: 50,
|
|
66
|
+
fontPath: null,
|
|
67
|
+
fontName: "Arial",
|
|
68
|
+
fontSize: 20,
|
|
69
|
+
color: "black",
|
|
70
|
+
maxWidth: null,
|
|
71
|
+
lineHeight: null,
|
|
72
|
+
textAlign: "left",
|
|
73
|
+
textBaseline: "top",
|
|
74
|
+
shadow: {
|
|
75
|
+
color: null,
|
|
76
|
+
offsetX: 0,
|
|
77
|
+
offsetY: 0,
|
|
78
|
+
blur: 0,
|
|
79
|
+
opacity: 0,
|
|
80
|
+
borderRadius: 0,
|
|
81
|
+
},
|
|
82
|
+
stroke: {
|
|
83
|
+
color: null,
|
|
84
|
+
width: 0,
|
|
85
|
+
borderRadius: 0,
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
this.frames = [];
|
|
89
|
+
this.defaultImageOptions = {
|
|
90
|
+
source: null,
|
|
91
|
+
x: 0,
|
|
92
|
+
y: 0,
|
|
93
|
+
width: null,
|
|
94
|
+
height: null,
|
|
95
|
+
filled: null,
|
|
96
|
+
borderRadius: null,
|
|
97
|
+
color: null,
|
|
98
|
+
gradient: null,
|
|
99
|
+
rotate: null,
|
|
100
|
+
shadow: {
|
|
101
|
+
color: null,
|
|
102
|
+
offsetX: 0,
|
|
103
|
+
offsetY: 0,
|
|
104
|
+
opacity: 0,
|
|
105
|
+
blur: 0,
|
|
106
|
+
borderRadius: null,
|
|
107
|
+
},
|
|
108
|
+
stroke: {
|
|
109
|
+
color: null,
|
|
110
|
+
width: null,
|
|
111
|
+
borderRadius: null,
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
this.defaultCanvasOptions = {
|
|
115
|
+
width: 500,
|
|
116
|
+
height: 300,
|
|
117
|
+
x: 0,
|
|
118
|
+
y: 0,
|
|
119
|
+
backgroundColor: null,
|
|
120
|
+
borderRadius: null,
|
|
121
|
+
backgroundGradient: null,
|
|
122
|
+
customBg: null,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
ApexPainter.prototype.validateFrameOptions = function (frame) {
|
|
126
|
+
if (!frame || typeof frame !== "object") {
|
|
127
|
+
throw new Error("Invalid frame options. Provide a valid object for frame configuration.");
|
|
128
|
+
}
|
|
129
|
+
if (typeof frame.delay !== "number" || frame.delay < 0) {
|
|
130
|
+
throw new Error("Frame delay must be a non-negative number.");
|
|
131
|
+
}
|
|
132
|
+
if (typeof frame.quality !== "number" ||
|
|
133
|
+
frame.quality < 1 ||
|
|
134
|
+
frame.quality > 100) {
|
|
135
|
+
throw new Error("Frame quality must be a number between 1 and 100.");
|
|
136
|
+
}
|
|
137
|
+
if (typeof frame.loop !== "number" || frame.loop < 0) {
|
|
138
|
+
throw new Error("Frame loop count must be a non-negative number.");
|
|
139
|
+
}
|
|
140
|
+
return true;
|
|
141
|
+
};
|
|
142
|
+
ApexPainter.prototype.validateImageOptions = function (imageOptions) {
|
|
143
|
+
if (!imageOptions || typeof imageOptions !== "object") {
|
|
144
|
+
throw new Error("Invalid image options. Provide a valid object for image configuration.");
|
|
145
|
+
}
|
|
146
|
+
if (!imageOptions.source) {
|
|
147
|
+
throw new Error("Image source is required.");
|
|
148
|
+
}
|
|
149
|
+
if (typeof imageOptions.x !== "number" ||
|
|
150
|
+
typeof imageOptions.y !== "number") {
|
|
151
|
+
throw new Error("Image x and y coordinates must be numbers.");
|
|
152
|
+
}
|
|
153
|
+
if (imageOptions.width &&
|
|
154
|
+
(typeof imageOptions.width !== "number" || imageOptions.width <= 0)) {
|
|
155
|
+
throw new Error("Image width must be a positive number.");
|
|
156
|
+
}
|
|
157
|
+
if (imageOptions.height &&
|
|
158
|
+
(typeof imageOptions.height !== "number" || imageOptions.height <= 0)) {
|
|
159
|
+
throw new Error("Image height must be a positive number.");
|
|
160
|
+
}
|
|
161
|
+
return true;
|
|
162
|
+
};
|
|
163
|
+
ApexPainter.prototype.validateTextOptions = function (textOptions) {
|
|
164
|
+
if (!textOptions || typeof textOptions !== "object") {
|
|
165
|
+
throw new Error("Invalid text options. Provide a valid object for text configuration.");
|
|
166
|
+
}
|
|
167
|
+
if (typeof textOptions.x !== "number" ||
|
|
168
|
+
typeof textOptions.y !== "number") {
|
|
169
|
+
throw new Error("Text x and y coordinates must be numbers.");
|
|
170
|
+
}
|
|
171
|
+
if (textOptions.fontSize &&
|
|
172
|
+
(typeof textOptions.fontSize !== "number" || textOptions.fontSize <= 0)) {
|
|
173
|
+
throw new Error("Text fontSize must be a positive number.");
|
|
174
|
+
}
|
|
175
|
+
return true;
|
|
176
|
+
};
|
|
177
|
+
ApexPainter.prototype.validateCanvasOptions = function (canvasOptions) {
|
|
178
|
+
if (!canvasOptions || typeof canvasOptions !== "object") {
|
|
179
|
+
throw new Error("Invalid canvas options. Provide a valid object for canvas configuration.");
|
|
180
|
+
}
|
|
181
|
+
if (typeof canvasOptions.width !== "number" ||
|
|
182
|
+
typeof canvasOptions.height !== "number") {
|
|
183
|
+
throw new Error("Canvas width and height must be numbers.");
|
|
184
|
+
}
|
|
185
|
+
if (canvasOptions.width <= 0 || canvasOptions.height <= 0) {
|
|
186
|
+
throw new Error("Canvas width and height must be positive values.");
|
|
187
|
+
}
|
|
188
|
+
return true;
|
|
189
|
+
};
|
|
190
|
+
ApexPainter.prototype.drawImages = function (imagesOptions, canvasOptions, baseDir) {
|
|
191
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
192
|
+
var mergedCanvasOptions, canvas, ctx, customBgImage, gradient, _i, imagesOptions_1, imageOptions;
|
|
193
|
+
return __generator(this, function (_a) {
|
|
194
|
+
switch (_a.label) {
|
|
195
|
+
case 0:
|
|
196
|
+
mergedCanvasOptions = this.mergeOptions(this.defaultCanvasOptions, canvasOptions);
|
|
197
|
+
this.validateCanvasOptions(mergedCanvasOptions);
|
|
198
|
+
if (!mergedCanvasOptions.customBg) return [3 /*break*/, 2];
|
|
199
|
+
if (typeof mergedCanvasOptions.customBg !== "string" ||
|
|
200
|
+
!mergedCanvasOptions.customBg.startsWith("http")) {
|
|
201
|
+
throw new Error("Invalid customBg URL");
|
|
202
|
+
}
|
|
203
|
+
return [4 /*yield*/, (0, canvas_1.loadImage)(mergedCanvasOptions.customBg)];
|
|
204
|
+
case 1:
|
|
205
|
+
customBgImage = _a.sent();
|
|
206
|
+
canvas = (0, canvas_1.createCanvas)(customBgImage.width, customBgImage.height);
|
|
207
|
+
ctx = canvas.getContext("2d");
|
|
208
|
+
this.drawRoundedRect(ctx, mergedCanvasOptions.x, mergedCanvasOptions.y, mergedCanvasOptions.width, mergedCanvasOptions.height, mergedCanvasOptions.borderRadius);
|
|
209
|
+
ctx.clip();
|
|
210
|
+
ctx.drawImage(customBgImage, 0, 0);
|
|
211
|
+
return [3 /*break*/, 3];
|
|
212
|
+
case 2:
|
|
213
|
+
canvas = (0, canvas_1.createCanvas)(mergedCanvasOptions.width, mergedCanvasOptions.height);
|
|
214
|
+
ctx = canvas.getContext("2d");
|
|
215
|
+
if (mergedCanvasOptions.backgroundGradient) {
|
|
216
|
+
gradient = this.createGradient(ctx, mergedCanvasOptions.backgroundGradient, mergedCanvasOptions.x, mergedCanvasOptions.y, mergedCanvasOptions.width, mergedCanvasOptions.height);
|
|
217
|
+
ctx.fillStyle = gradient;
|
|
218
|
+
this.drawRoundedRect(ctx, mergedCanvasOptions.x, mergedCanvasOptions.y, mergedCanvasOptions.width, mergedCanvasOptions.height, mergedCanvasOptions.borderRadius);
|
|
219
|
+
ctx.fill();
|
|
220
|
+
}
|
|
221
|
+
else if (mergedCanvasOptions.backgroundColor) {
|
|
222
|
+
if (mergedCanvasOptions.borderRadius) {
|
|
223
|
+
this.drawRoundedRect(ctx, mergedCanvasOptions.x, mergedCanvasOptions.y, mergedCanvasOptions.width, mergedCanvasOptions.height, mergedCanvasOptions.borderRadius);
|
|
224
|
+
ctx.fillStyle = mergedCanvasOptions.backgroundColor;
|
|
225
|
+
ctx.fill();
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
ctx.fillStyle = mergedCanvasOptions.backgroundColor;
|
|
229
|
+
ctx.fillRect(mergedCanvasOptions.x, mergedCanvasOptions.y, mergedCanvasOptions.width, mergedCanvasOptions.height);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
_a.label = 3;
|
|
233
|
+
case 3:
|
|
234
|
+
if (!(imagesOptions && imagesOptions.length > 0)) return [3 /*break*/, 7];
|
|
235
|
+
_i = 0, imagesOptions_1 = imagesOptions;
|
|
236
|
+
_a.label = 4;
|
|
237
|
+
case 4:
|
|
238
|
+
if (!(_i < imagesOptions_1.length)) return [3 /*break*/, 7];
|
|
239
|
+
imageOptions = imagesOptions_1[_i];
|
|
240
|
+
return [4 /*yield*/, this.drawSingleImage(ctx, imageOptions, baseDir)];
|
|
241
|
+
case 5:
|
|
242
|
+
_a.sent();
|
|
243
|
+
_a.label = 6;
|
|
244
|
+
case 6:
|
|
245
|
+
_i++;
|
|
246
|
+
return [3 /*break*/, 4];
|
|
247
|
+
case 7: return [2 /*return*/, canvas.toBuffer("image/png")];
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
};
|
|
252
|
+
///////Drawing single images
|
|
253
|
+
ApexPainter.prototype.drawSingleImage = function (ctx, imageOptions, baseDir) {
|
|
254
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
255
|
+
var mergedImageOptions, image, imagePath, shadowX, shadowY;
|
|
256
|
+
return __generator(this, function (_a) {
|
|
257
|
+
switch (_a.label) {
|
|
258
|
+
case 0:
|
|
259
|
+
mergedImageOptions = this.mergeOptions(this.defaultImageOptions, imageOptions);
|
|
260
|
+
this.validateImageOptions(imageOptions);
|
|
261
|
+
// Check if the source is a shape name
|
|
262
|
+
if (mergedImageOptions.source &&
|
|
263
|
+
this.isShapeName(mergedImageOptions.source)) {
|
|
264
|
+
this.drawShape(ctx, mergedImageOptions);
|
|
265
|
+
return [2 /*return*/];
|
|
266
|
+
}
|
|
267
|
+
if (!mergedImageOptions.source) return [3 /*break*/, 10];
|
|
268
|
+
image = void 0;
|
|
269
|
+
if (!baseDir) return [3 /*break*/, 5];
|
|
270
|
+
imagePath = path_1.join(baseDir, mergedImageOptions.source);
|
|
271
|
+
if (!(mergedImageOptions.source.startsWith("http") ||
|
|
272
|
+
mergedImageOptions.source.startsWith("https"))) return [3 /*break*/, 2];
|
|
273
|
+
return [4 /*yield*/, (0, canvas_1.loadImage)(mergedImageOptions.source)];
|
|
274
|
+
case 1:
|
|
275
|
+
image = _a.sent();
|
|
276
|
+
return [3 /*break*/, 4];
|
|
277
|
+
case 2: return [4 /*yield*/, (0, canvas_1.loadImage)(imagePath)];
|
|
278
|
+
case 3:
|
|
279
|
+
image = _a.sent();
|
|
280
|
+
_a.label = 4;
|
|
281
|
+
case 4: return [3 /*break*/, 9];
|
|
282
|
+
case 5:
|
|
283
|
+
if (!(mergedImageOptions.source.startsWith("http") ||
|
|
284
|
+
mergedImageOptions.source.startsWith("https"))) return [3 /*break*/, 7];
|
|
285
|
+
return [4 /*yield*/, (0, canvas_1.loadImage)(mergedImageOptions.source)];
|
|
286
|
+
case 6:
|
|
287
|
+
image = _a.sent();
|
|
288
|
+
return [3 /*break*/, 9];
|
|
289
|
+
case 7: return [4 /*yield*/, (0, canvas_1.loadImage)(mergedImageOptions.source)];
|
|
290
|
+
case 8:
|
|
291
|
+
image = _a.sent();
|
|
292
|
+
_a.label = 9;
|
|
293
|
+
case 9:
|
|
294
|
+
// Save the initial context state
|
|
295
|
+
ctx.save();
|
|
296
|
+
// Apply shadow if provided
|
|
297
|
+
if (mergedImageOptions.shadow &&
|
|
298
|
+
mergedImageOptions.shadow.offsetX &&
|
|
299
|
+
mergedImageOptions.shadow.offsetY) {
|
|
300
|
+
ctx.globalAlpha = mergedImageOptions.shadow.opacity || null;
|
|
301
|
+
ctx.filter = "blur(".concat(mergedImageOptions.shadow.blur || null, "px)");
|
|
302
|
+
shadowX = mergedImageOptions.x + (mergedImageOptions.shadow.offsetX || 0);
|
|
303
|
+
shadowY = mergedImageOptions.y + (mergedImageOptions.shadow.offsetY || 0);
|
|
304
|
+
this.drawRoundedRect(ctx, shadowX, shadowY, mergedImageOptions.width, mergedImageOptions.height, mergedImageOptions.shadow.borderRadius || 0);
|
|
305
|
+
ctx.fillStyle = mergedImageOptions.shadow.color || "transparent";
|
|
306
|
+
ctx.fill();
|
|
307
|
+
}
|
|
308
|
+
// Reset filter and opacity properties
|
|
309
|
+
ctx.filter = "none";
|
|
310
|
+
ctx.globalAlpha = 1;
|
|
311
|
+
// Draw the actual image
|
|
312
|
+
this.drawRoundedImage(ctx, image, mergedImageOptions.x, mergedImageOptions.y, mergedImageOptions.width, mergedImageOptions.height, mergedImageOptions.borderRadius || 0);
|
|
313
|
+
// Restore the context state
|
|
314
|
+
ctx.restore();
|
|
315
|
+
// Apply stroke if provided
|
|
316
|
+
if (mergedImageOptions.stroke &&
|
|
317
|
+
mergedImageOptions.stroke.color &&
|
|
318
|
+
mergedImageOptions.stroke.width) {
|
|
319
|
+
ctx.strokeStyle = mergedImageOptions.stroke.color || "transparent"; // Change color as needed
|
|
320
|
+
ctx.lineWidth = mergedImageOptions.stroke.width || 1;
|
|
321
|
+
// Draw the rounded rectangle for stroke
|
|
322
|
+
this.drawRoundedRect(ctx, mergedImageOptions.x, mergedImageOptions.y, mergedImageOptions.width, mergedImageOptions.height, mergedImageOptions.stroke.borderRadius || 0);
|
|
323
|
+
ctx.stroke();
|
|
324
|
+
}
|
|
325
|
+
ctx.restore();
|
|
326
|
+
_a.label = 10;
|
|
327
|
+
case 10: return [2 /*return*/];
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
};
|
|
332
|
+
ApexPainter.prototype.isShapeName = function (source) {
|
|
333
|
+
var validShapes = ["square", "circle", "triangle", "rectangle", "pentagon"];
|
|
334
|
+
return validShapes.includes(source.toLowerCase());
|
|
335
|
+
};
|
|
336
|
+
ApexPainter.prototype.drawShape = function (ctx, shapeOptions) {
|
|
337
|
+
var source = shapeOptions.source, x = shapeOptions.x, y = shapeOptions.y, width = shapeOptions.width, height = shapeOptions.height, borderRadius = shapeOptions.borderRadius, stroke = shapeOptions.stroke, color = shapeOptions.color, rotate = shapeOptions.rotate, filled = shapeOptions.filled, gradient = shapeOptions.gradient, shadow = shapeOptions.shadow;
|
|
338
|
+
var isFilled = filled !== undefined ? filled : true;
|
|
339
|
+
// Save the initial context state
|
|
340
|
+
ctx.save();
|
|
341
|
+
// Apply shadow if provided
|
|
342
|
+
if (shadow && shadow.offsetX && shadow.offsetY) {
|
|
343
|
+
ctx.globalAlpha = shadow.opacity || null;
|
|
344
|
+
ctx.filter = "blur(".concat(shadow.blur || null, "px)");
|
|
345
|
+
var shadowX = x + (shadow.offsetX || 0);
|
|
346
|
+
var shadowY = y + (shadow.offsetY || 0);
|
|
347
|
+
this.drawRoundedRect(ctx, shadowX, shadowY, width, height, shadow.borderRadius || 0);
|
|
348
|
+
ctx.fillStyle = shadow.color || "transparent";
|
|
349
|
+
ctx.fill();
|
|
350
|
+
}
|
|
351
|
+
// Reset filter property
|
|
352
|
+
ctx.filter = "none";
|
|
353
|
+
ctx.globalAlpha = 1;
|
|
354
|
+
if (rotate) {
|
|
355
|
+
var centerX = x + width / 2;
|
|
356
|
+
var centerY = y + height / 2;
|
|
357
|
+
ctx.translate(centerX, centerY);
|
|
358
|
+
ctx.rotate((rotate * Math.PI) / 180);
|
|
359
|
+
ctx.translate(-centerX, -centerY);
|
|
360
|
+
}
|
|
361
|
+
if (gradient) {
|
|
362
|
+
var gradientFill = typeof gradient === 'string'
|
|
363
|
+
? gradient
|
|
364
|
+
: this.createGradient(ctx, gradient, x, y, x + width, y + height);
|
|
365
|
+
ctx.fillStyle = gradientFill;
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
ctx.fillStyle = color || "transparent";
|
|
369
|
+
}
|
|
370
|
+
ctx.beginPath();
|
|
371
|
+
switch (source.toLowerCase()) {
|
|
372
|
+
case "square":
|
|
373
|
+
this.drawRoundedRect(ctx, x, y, width, height, borderRadius || 0);
|
|
374
|
+
break;
|
|
375
|
+
case "circle":
|
|
376
|
+
var circleRadius = Math.min(width, height) / 2;
|
|
377
|
+
ctx.arc(x + width / 2, y + height / 2, circleRadius, 0, 2 * Math.PI);
|
|
378
|
+
break;
|
|
379
|
+
case "triangle":
|
|
380
|
+
ctx.moveTo(x + width / 2, y);
|
|
381
|
+
ctx.lineTo(x + width, y + height);
|
|
382
|
+
ctx.lineTo(x, y + height);
|
|
383
|
+
ctx.closePath();
|
|
384
|
+
break;
|
|
385
|
+
case "pentagon":
|
|
386
|
+
var sideLength = Math.min(width, height);
|
|
387
|
+
for (var i = 0; i < 5; i++) {
|
|
388
|
+
var angle = (i * 2 * Math.PI) / 5;
|
|
389
|
+
var px = x + width / 2 + sideLength * Math.cos(angle);
|
|
390
|
+
var py = y + height / 2 + sideLength * Math.sin(angle);
|
|
391
|
+
if (i === 0) {
|
|
392
|
+
ctx.moveTo(px, py);
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
ctx.lineTo(px, py);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
ctx.closePath();
|
|
399
|
+
break;
|
|
400
|
+
// Add cases for other shapes
|
|
401
|
+
default:
|
|
402
|
+
console.error("Unsupported shape: ".concat(source));
|
|
403
|
+
}
|
|
404
|
+
if (isFilled) {
|
|
405
|
+
ctx.fill();
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
ctx.stroke();
|
|
409
|
+
}
|
|
410
|
+
ctx.restore();
|
|
411
|
+
if (stroke && stroke.color !== undefined && stroke.width !== undefined) {
|
|
412
|
+
ctx.strokeStyle = stroke.color || "transparent";
|
|
413
|
+
ctx.lineWidth = stroke.width || 1;
|
|
414
|
+
ctx.save();
|
|
415
|
+
if (rotate) {
|
|
416
|
+
var centerX = x + width / 2;
|
|
417
|
+
var centerY = y + height / 2;
|
|
418
|
+
ctx.translate(centerX, centerY);
|
|
419
|
+
ctx.rotate((rotate * Math.PI) / 180);
|
|
420
|
+
ctx.translate(-centerX, -centerY);
|
|
421
|
+
}
|
|
422
|
+
ctx.fillStyle = "transparent";
|
|
423
|
+
this.drawRoundedRect(ctx, x, y, width, height, stroke.borderRadius || 0);
|
|
424
|
+
ctx.stroke();
|
|
425
|
+
ctx.restore();
|
|
426
|
+
}
|
|
427
|
+
ctx.restore();
|
|
428
|
+
};
|
|
429
|
+
ApexPainter.prototype.addText = function (textOptionsArray, buffer, baseDir) {
|
|
430
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
431
|
+
var existingImage, canvas, ctx, _i, textOptionsArray_1, textOptions, mergedTextOptions, error_1;
|
|
432
|
+
return __generator(this, function (_a) {
|
|
433
|
+
switch (_a.label) {
|
|
434
|
+
case 0:
|
|
435
|
+
_a.trys.push([0, 2, , 3]);
|
|
436
|
+
return [4 /*yield*/, (0, canvas_1.loadImage)(buffer)];
|
|
437
|
+
case 1:
|
|
438
|
+
existingImage = _a.sent();
|
|
439
|
+
canvas = (0, canvas_1.createCanvas)(existingImage.width, existingImage.height);
|
|
440
|
+
ctx = canvas.getContext("2d");
|
|
441
|
+
ctx.drawImage(existingImage, 0, 0);
|
|
442
|
+
for (_i = 0, textOptionsArray_1 = textOptionsArray; _i < textOptionsArray_1.length; _i++) {
|
|
443
|
+
textOptions = textOptionsArray_1[_i];
|
|
444
|
+
this.validateTextOptions(textOptions);
|
|
445
|
+
mergedTextOptions = this.mergeOptions(this.defaultTextOptions, textOptions);
|
|
446
|
+
if (mergedTextOptions.fontPath) {
|
|
447
|
+
if (!baseDir) {
|
|
448
|
+
throw new Error("You need to mention __dirname in the textOptions");
|
|
449
|
+
}
|
|
450
|
+
canvas_1.GlobalFonts.registerFromPath(path_1.join(baseDir, mergedTextOptions.fontPath), mergedTextOptions.fontName);
|
|
451
|
+
ctx.font = "".concat(mergedTextOptions.fontSize, "px ").concat(mergedTextOptions.fontName || "Arial");
|
|
452
|
+
}
|
|
453
|
+
else {
|
|
454
|
+
ctx.font = "".concat(mergedTextOptions.fontSize, "px ").concat(mergedTextOptions.fontName || "Arial");
|
|
455
|
+
}
|
|
456
|
+
this.drawText(ctx, mergedTextOptions);
|
|
457
|
+
}
|
|
458
|
+
return [2 /*return*/, canvas.toBuffer("image/png")];
|
|
459
|
+
case 2:
|
|
460
|
+
error_1 = _a.sent();
|
|
461
|
+
// Handle the case where the buffer is not a valid image
|
|
462
|
+
console.error("Error loading existing image:", error_1);
|
|
463
|
+
throw new Error("Invalid image buffer");
|
|
464
|
+
case 3: return [2 /*return*/];
|
|
465
|
+
}
|
|
466
|
+
});
|
|
467
|
+
});
|
|
468
|
+
};
|
|
469
|
+
ApexPainter.prototype.drawText = function (ctx, textOptions) {
|
|
470
|
+
var mergedTextOptions = this.mergeOptions(this.defaultTextOptions, textOptions);
|
|
471
|
+
// Save the initial context state
|
|
472
|
+
ctx.save();
|
|
473
|
+
ctx.font = "".concat(mergedTextOptions.fontSize, "px ").concat(mergedTextOptions.fontName);
|
|
474
|
+
ctx.textAlign = mergedTextOptions.textAlign;
|
|
475
|
+
ctx.textBaseline = mergedTextOptions.textBaseline;
|
|
476
|
+
// Apply shadow if provided
|
|
477
|
+
if (mergedTextOptions.shadow &&
|
|
478
|
+
mergedTextOptions.shadow.offsetX !== undefined &&
|
|
479
|
+
mergedTextOptions.shadow.offsetY !== undefined) {
|
|
480
|
+
ctx.shadowColor = mergedTextOptions.shadow.color || "transparent";
|
|
481
|
+
ctx.shadowOffsetX = mergedTextOptions.shadow.offsetX;
|
|
482
|
+
ctx.shadowOffsetY = mergedTextOptions.shadow.offsetY;
|
|
483
|
+
ctx.shadowBlur = mergedTextOptions.shadow.blur || 0;
|
|
484
|
+
}
|
|
485
|
+
// Set fill color
|
|
486
|
+
ctx.fillStyle = mergedTextOptions.color;
|
|
487
|
+
// Draw the text
|
|
488
|
+
ctx.fillText(mergedTextOptions.text, mergedTextOptions.x, mergedTextOptions.y);
|
|
489
|
+
// Draw the text stroke if provided
|
|
490
|
+
if (mergedTextOptions.stroke &&
|
|
491
|
+
mergedTextOptions.stroke.color &&
|
|
492
|
+
mergedTextOptions.stroke.width) {
|
|
493
|
+
ctx.strokeStyle = mergedTextOptions.stroke.color;
|
|
494
|
+
ctx.lineWidth = mergedTextOptions.stroke.width;
|
|
495
|
+
// Draw the text stroke
|
|
496
|
+
ctx.strokeText(mergedTextOptions.text, mergedTextOptions.x, mergedTextOptions.y);
|
|
497
|
+
}
|
|
498
|
+
ctx.restore();
|
|
499
|
+
};
|
|
500
|
+
ApexPainter.prototype.mergeOptions = function (defaultOptions, userOptions) {
|
|
501
|
+
var mergedOptions = __assign({}, defaultOptions);
|
|
502
|
+
for (var key in userOptions) {
|
|
503
|
+
if (userOptions[key] !== null && userOptions[key] !== undefined) {
|
|
504
|
+
if (typeof userOptions[key] === 'object' &&
|
|
505
|
+
defaultOptions[key] !== null &&
|
|
506
|
+
defaultOptions[key] !== undefined) {
|
|
507
|
+
mergedOptions[key] = this.mergeOptions(defaultOptions[key], userOptions[key]);
|
|
508
|
+
}
|
|
509
|
+
else {
|
|
510
|
+
mergedOptions[key] = userOptions[key];
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
return mergedOptions;
|
|
515
|
+
};
|
|
516
|
+
ApexPainter.prototype.createGradient = function (ctx, gradientOptions, startX, startY, endX, endY) {
|
|
517
|
+
if (!gradientOptions || !gradientOptions.type) {
|
|
518
|
+
throw new Error("Invalid gradient options. Provide a valid object with a type property.");
|
|
519
|
+
}
|
|
520
|
+
if (gradientOptions.type === "linear") {
|
|
521
|
+
if (typeof startX !== "number" ||
|
|
522
|
+
typeof startY !== "number" ||
|
|
523
|
+
typeof endX !== "number" ||
|
|
524
|
+
typeof endY !== "number") {
|
|
525
|
+
throw new Error("Invalid gradient options for linear gradient. Numeric values are required for startX, startY, endX, and endY.");
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
else if (gradientOptions.type === "radial") {
|
|
529
|
+
if (typeof gradientOptions.startX !== "number" ||
|
|
530
|
+
typeof gradientOptions.startY !== "number" ||
|
|
531
|
+
typeof gradientOptions.startRadius !== "number" ||
|
|
532
|
+
typeof gradientOptions.endX !== "number" ||
|
|
533
|
+
typeof gradientOptions.endY !== "number" ||
|
|
534
|
+
typeof gradientOptions.endRadius !== "number") {
|
|
535
|
+
throw new Error("Invalid gradient options for radial gradient. Numeric values are required for startX, startY, startRadius, endX, endY, and endRadius.");
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
else {
|
|
539
|
+
throw new Error('Unsupported gradient type. Use "linear" or "radial".');
|
|
540
|
+
}
|
|
541
|
+
var gradient = gradientOptions.type === "linear"
|
|
542
|
+
? ctx.createLinearGradient(startX, startY, endX, endY)
|
|
543
|
+
: ctx.createRadialGradient(gradientOptions.startX, gradientOptions.startY, gradientOptions.startRadius, gradientOptions.endX, gradientOptions.endY, gradientOptions.endRadius);
|
|
544
|
+
for (var _i = 0, _a = gradientOptions.colors; _i < _a.length; _i++) {
|
|
545
|
+
var colorStop = _a[_i];
|
|
546
|
+
gradient.addColorStop(colorStop.stop, colorStop.color);
|
|
547
|
+
}
|
|
548
|
+
return gradient;
|
|
549
|
+
};
|
|
550
|
+
ApexPainter.prototype.drawRoundedImage = function (ctx, image, x, y, width, height, borderRadius) {
|
|
551
|
+
ctx.save();
|
|
552
|
+
ctx.beginPath();
|
|
553
|
+
if (borderRadius === "circular") {
|
|
554
|
+
var circleRadius = Math.min(width, height) / 2;
|
|
555
|
+
ctx.arc(x + width / 2, y + height / 2, circleRadius, 0, 2 * Math.PI);
|
|
556
|
+
}
|
|
557
|
+
else {
|
|
558
|
+
ctx.moveTo(x + borderRadius, y);
|
|
559
|
+
ctx.lineTo(x + width - borderRadius, y);
|
|
560
|
+
ctx.quadraticCurveTo(x + width, y, x + width, y + borderRadius);
|
|
561
|
+
ctx.lineTo(x + width, y + height - borderRadius);
|
|
562
|
+
ctx.quadraticCurveTo(x + width, y + height, x + width - borderRadius, y + height);
|
|
563
|
+
ctx.lineTo(x + borderRadius, y + height);
|
|
564
|
+
ctx.quadraticCurveTo(x, y + height, x, y + height - borderRadius);
|
|
565
|
+
ctx.lineTo(x, y + borderRadius);
|
|
566
|
+
ctx.quadraticCurveTo(x, y, x + borderRadius, y);
|
|
567
|
+
}
|
|
568
|
+
ctx.closePath();
|
|
569
|
+
ctx.clip();
|
|
570
|
+
ctx.drawImage(image, x, y, width, height);
|
|
571
|
+
ctx.restore();
|
|
572
|
+
};
|
|
573
|
+
ApexPainter.prototype.drawRoundedRect = function (ctx, x, y, width, height, borderRadius) {
|
|
574
|
+
if (borderRadius === "circular") {
|
|
575
|
+
var circleRadius = Math.min(width, height) / 2;
|
|
576
|
+
ctx.beginPath();
|
|
577
|
+
ctx.arc(x + width / 2, y + height / 2, circleRadius, 0, 2 * Math.PI);
|
|
578
|
+
ctx.closePath();
|
|
579
|
+
}
|
|
580
|
+
else if (borderRadius) {
|
|
581
|
+
ctx.beginPath();
|
|
582
|
+
ctx.moveTo(x + borderRadius, y);
|
|
583
|
+
ctx.lineTo(x + width - borderRadius, y);
|
|
584
|
+
ctx.quadraticCurveTo(x + width, y, x + width, y + borderRadius);
|
|
585
|
+
ctx.lineTo(x + width, y + height - borderRadius);
|
|
586
|
+
ctx.quadraticCurveTo(x + width, y + height, x + width - borderRadius, y + height);
|
|
587
|
+
ctx.lineTo(x + borderRadius, y + height);
|
|
588
|
+
ctx.quadraticCurveTo(x, y + height, x, y + height - borderRadius);
|
|
589
|
+
ctx.lineTo(x, y + borderRadius);
|
|
590
|
+
ctx.quadraticCurveTo(x, y, x + borderRadius, y);
|
|
591
|
+
ctx.closePath();
|
|
592
|
+
}
|
|
593
|
+
else {
|
|
594
|
+
ctx.rect(x, y, width, height);
|
|
595
|
+
}
|
|
596
|
+
};
|
|
597
|
+
ApexPainter.prototype.loadImageFromPathOrURL = function (imagePath, baseDir) {
|
|
598
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
599
|
+
var response, absolutePath, error_2;
|
|
600
|
+
return __generator(this, function (_a) {
|
|
601
|
+
switch (_a.label) {
|
|
602
|
+
case 0:
|
|
603
|
+
_a.trys.push([0, 4, , 5]);
|
|
604
|
+
if (!imagePath) {
|
|
605
|
+
throw new Error("Image path is required.");
|
|
606
|
+
}
|
|
607
|
+
if (!imagePath.startsWith("http")) return [3 /*break*/, 2];
|
|
608
|
+
if (baseDir) {
|
|
609
|
+
throw new Error("No need for baseDir when using an image URL.");
|
|
610
|
+
}
|
|
611
|
+
return [4 /*yield*/, axios_1.get(imagePath, {
|
|
612
|
+
responseType: "arraybuffer",
|
|
613
|
+
})];
|
|
614
|
+
case 1:
|
|
615
|
+
response = _a.sent();
|
|
616
|
+
return [2 /*return*/, (0, sharp_1.default)(Buffer.from(response.data))];
|
|
617
|
+
case 2:
|
|
618
|
+
if (!baseDir) {
|
|
619
|
+
throw new Error("baseDir is required for local file paths.");
|
|
620
|
+
}
|
|
621
|
+
absolutePath = path_1.resolve(baseDir, imagePath);
|
|
622
|
+
return [2 /*return*/, (0, sharp_1.default)(absolutePath)];
|
|
623
|
+
case 3: return [3 /*break*/, 5];
|
|
624
|
+
case 4:
|
|
625
|
+
error_2 = _a.sent();
|
|
626
|
+
console.error("Error loading image:", error_2);
|
|
627
|
+
throw new Error("Failed to load image");
|
|
628
|
+
case 5: return [2 /*return*/];
|
|
629
|
+
}
|
|
630
|
+
});
|
|
631
|
+
});
|
|
632
|
+
};
|
|
633
|
+
ApexPainter.prototype.resize = function (resizeOptions, baseDir) {
|
|
634
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
635
|
+
var imagePath, resizedBuffer_1, image, resizedBuffer, error_3;
|
|
636
|
+
return __generator(this, function (_a) {
|
|
637
|
+
switch (_a.label) {
|
|
638
|
+
case 0:
|
|
639
|
+
_a.trys.push([0, 5, , 6]);
|
|
640
|
+
if (!resizeOptions.imagePath) {
|
|
641
|
+
throw new Error("Image path is required for resizing.");
|
|
642
|
+
}
|
|
643
|
+
imagePath = void 0;
|
|
644
|
+
if (!Buffer.isBuffer(resizeOptions.imagePath)) return [3 /*break*/, 2];
|
|
645
|
+
return [4 /*yield*/, (0, sharp_1.default)(resizeOptions.imagePath)
|
|
646
|
+
.resize(resizeOptions.size.width, resizeOptions.size.height)
|
|
647
|
+
.toBuffer()];
|
|
648
|
+
case 1:
|
|
649
|
+
resizedBuffer_1 = _a.sent();
|
|
650
|
+
return [2 /*return*/, resizedBuffer_1];
|
|
651
|
+
case 2:
|
|
652
|
+
if (resizeOptions.imagePath.startsWith("http")) {
|
|
653
|
+
if (baseDir) {
|
|
654
|
+
throw new Error("No need for baseDir when using an image URL.");
|
|
655
|
+
}
|
|
656
|
+
imagePath = resizeOptions.imagePath;
|
|
657
|
+
}
|
|
658
|
+
else {
|
|
659
|
+
if (!baseDir) {
|
|
660
|
+
throw new Error("baseDir is required for local file paths.");
|
|
661
|
+
}
|
|
662
|
+
imagePath = path_1.resolve(baseDir, resizeOptions.imagePath);
|
|
663
|
+
}
|
|
664
|
+
return [4 /*yield*/, this.loadImageFromPathOrURL(imagePath)];
|
|
665
|
+
case 3:
|
|
666
|
+
image = _a.sent();
|
|
667
|
+
return [4 /*yield*/, image.resize(resizeOptions.size).toBuffer()];
|
|
668
|
+
case 4:
|
|
669
|
+
resizedBuffer = _a.sent();
|
|
670
|
+
return [2 /*return*/, resizedBuffer];
|
|
671
|
+
case 5:
|
|
672
|
+
error_3 = _a.sent();
|
|
673
|
+
console.error("Error resizing image:", error_3);
|
|
674
|
+
throw new Error("Failed to resize image");
|
|
675
|
+
case 6: return [2 /*return*/];
|
|
676
|
+
}
|
|
677
|
+
});
|
|
678
|
+
});
|
|
679
|
+
};
|
|
680
|
+
ApexPainter.prototype.imageConverter = function (options) {
|
|
681
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
682
|
+
var image, response, absolutePath, convertedBuffer, error_4;
|
|
683
|
+
return __generator(this, function (_a) {
|
|
684
|
+
switch (_a.label) {
|
|
685
|
+
case 0:
|
|
686
|
+
_a.trys.push([0, 5, , 6]);
|
|
687
|
+
image = void 0;
|
|
688
|
+
if (!options.imagePath.startsWith("http")) return [3 /*break*/, 2];
|
|
689
|
+
return [4 /*yield*/, axios_1.get(options.imagePath, {
|
|
690
|
+
responseType: "arraybuffer",
|
|
691
|
+
})];
|
|
692
|
+
case 1:
|
|
693
|
+
response = _a.sent();
|
|
694
|
+
image = (0, sharp_1.default)(Buffer.from(response.data));
|
|
695
|
+
return [3 /*break*/, 3];
|
|
696
|
+
case 2:
|
|
697
|
+
if (!options.imagePath) {
|
|
698
|
+
throw new Error("Image path is required.");
|
|
699
|
+
}
|
|
700
|
+
if (!options.baseDir) {
|
|
701
|
+
throw new Error("baseDir is required for local file paths.");
|
|
702
|
+
}
|
|
703
|
+
absolutePath = path_1.resolve(options.baseDir, options.imagePath);
|
|
704
|
+
image = (0, sharp_1.default)(absolutePath);
|
|
705
|
+
_a.label = 3;
|
|
706
|
+
case 3: return [4 /*yield*/, image.toFormat(options.newExtension).toBuffer()];
|
|
707
|
+
case 4:
|
|
708
|
+
convertedBuffer = _a.sent();
|
|
709
|
+
return [2 /*return*/, convertedBuffer];
|
|
710
|
+
case 5:
|
|
711
|
+
error_4 = _a.sent();
|
|
712
|
+
console.error("Error changing image extension:", error_4);
|
|
713
|
+
throw new Error("Failed to change image extension");
|
|
714
|
+
case 6: return [2 /*return*/];
|
|
715
|
+
}
|
|
716
|
+
});
|
|
717
|
+
});
|
|
718
|
+
};
|
|
719
|
+
ApexPainter.prototype.processImage = function (options) {
|
|
720
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
721
|
+
var jimpImage, pngBuffer, imagePathResolved, _i, _a, filter, outputMimeType, error_5;
|
|
722
|
+
return __generator(this, function (_b) {
|
|
723
|
+
switch (_b.label) {
|
|
724
|
+
case 0:
|
|
725
|
+
_b.trys.push([0, 7, , 8]);
|
|
726
|
+
jimpImage = void 0;
|
|
727
|
+
if (!options.imagePath.startsWith("http")) return [3 /*break*/, 3];
|
|
728
|
+
return [4 /*yield*/, this.imageConverter({
|
|
729
|
+
imagePath: options.imagePath,
|
|
730
|
+
newExtension: "png",
|
|
731
|
+
baseDir: options.baseDir !== null ? options.baseDir : undefined,
|
|
732
|
+
})];
|
|
733
|
+
case 1:
|
|
734
|
+
pngBuffer = _b.sent();
|
|
735
|
+
return [4 /*yield*/, jimp_1.read(pngBuffer)];
|
|
736
|
+
case 2:
|
|
737
|
+
jimpImage = _b.sent();
|
|
738
|
+
return [3 /*break*/, 5];
|
|
739
|
+
case 3:
|
|
740
|
+
if (!options.baseDir) {
|
|
741
|
+
throw new Error("You need to provide __dirname in options.");
|
|
742
|
+
}
|
|
743
|
+
imagePathResolved = options.baseDir
|
|
744
|
+
? path_1.resolve(options.baseDir, options.imagePath)
|
|
745
|
+
: options.imagePath;
|
|
746
|
+
return [4 /*yield*/, jimp_1.read(imagePathResolved)];
|
|
747
|
+
case 4:
|
|
748
|
+
jimpImage = _b.sent();
|
|
749
|
+
_b.label = 5;
|
|
750
|
+
case 5:
|
|
751
|
+
for (_i = 0, _a = options.filters; _i < _a.length; _i++) {
|
|
752
|
+
filter = _a[_i];
|
|
753
|
+
switch (filter.type) {
|
|
754
|
+
case "flip":
|
|
755
|
+
jimpImage.flip(filter.horizontal, filter.vertical);
|
|
756
|
+
break;
|
|
757
|
+
case "mirror":
|
|
758
|
+
jimpImage.mirror(filter.horizontal, filter.vertical);
|
|
759
|
+
break;
|
|
760
|
+
case "rotate":
|
|
761
|
+
jimpImage.rotate(filter.deg, filter.mode);
|
|
762
|
+
break;
|
|
763
|
+
case "brightness":
|
|
764
|
+
jimpImage.brightness(filter.value);
|
|
765
|
+
break;
|
|
766
|
+
case "contrast":
|
|
767
|
+
jimpImage.contrast(filter.value);
|
|
768
|
+
break;
|
|
769
|
+
case "dither565":
|
|
770
|
+
jimpImage.dither565();
|
|
771
|
+
break;
|
|
772
|
+
case "greyscale":
|
|
773
|
+
jimpImage.greyscale();
|
|
774
|
+
break;
|
|
775
|
+
case "invert":
|
|
776
|
+
jimpImage.invert();
|
|
777
|
+
break;
|
|
778
|
+
case "normalize":
|
|
779
|
+
jimpImage.normalize();
|
|
780
|
+
break;
|
|
781
|
+
case "autocrop":
|
|
782
|
+
jimpImage.autocrop(filter.tolerance || 0);
|
|
783
|
+
break;
|
|
784
|
+
case "crop":
|
|
785
|
+
jimpImage.crop(filter.x, filter.y, filter.w, filter.h);
|
|
786
|
+
break;
|
|
787
|
+
case "fade":
|
|
788
|
+
jimpImage.fade(filter.factor);
|
|
789
|
+
break;
|
|
790
|
+
case "opacity":
|
|
791
|
+
jimpImage.opacity(filter.factor);
|
|
792
|
+
break;
|
|
793
|
+
case "opaque":
|
|
794
|
+
jimpImage.opaque();
|
|
795
|
+
break;
|
|
796
|
+
case "gaussian":
|
|
797
|
+
jimpImage.gaussian(filter.radius);
|
|
798
|
+
break;
|
|
799
|
+
case "blur":
|
|
800
|
+
jimpImage.blur(filter.radius);
|
|
801
|
+
break;
|
|
802
|
+
case "posterize":
|
|
803
|
+
jimpImage.posterize(filter.levels);
|
|
804
|
+
break;
|
|
805
|
+
case "sepia":
|
|
806
|
+
jimpImage.sepia();
|
|
807
|
+
break;
|
|
808
|
+
case "pixelate":
|
|
809
|
+
jimpImage.pixelate(filter.size, filter.x, filter.y, filter.w, filter.h);
|
|
810
|
+
break;
|
|
811
|
+
default:
|
|
812
|
+
console.error("Unsupported filter type: ".concat(filter.type));
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
outputMimeType = jimpImage._originalMime || jimp_1.MIME_PNG;
|
|
816
|
+
return [4 /*yield*/, jimpImage.getBufferAsync(outputMimeType)];
|
|
817
|
+
case 6: return [2 /*return*/, _b.sent()];
|
|
818
|
+
case 7:
|
|
819
|
+
error_5 = _b.sent();
|
|
820
|
+
console.error("Error processing image:", error_5.message);
|
|
821
|
+
console.error(error_5.stack);
|
|
822
|
+
throw new Error("Failed to process image");
|
|
823
|
+
case 8: return [2 /*return*/];
|
|
824
|
+
}
|
|
825
|
+
});
|
|
826
|
+
});
|
|
827
|
+
};
|
|
828
|
+
ApexPainter.prototype.validateColor = function (filterColor) {
|
|
829
|
+
var hexColorRegex = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
|
|
830
|
+
var isHexColor = hexColorRegex.test(filterColor);
|
|
831
|
+
if (!isHexColor) {
|
|
832
|
+
throw new Error("Invalid color format. Only hex colors are supported.");
|
|
833
|
+
}
|
|
834
|
+
return true;
|
|
835
|
+
};
|
|
836
|
+
ApexPainter.prototype.colorFilters = function (options) {
|
|
837
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
838
|
+
var jimpImage, pngBuffer, imagePathResolved, resultBuffer, error_6;
|
|
839
|
+
return __generator(this, function (_a) {
|
|
840
|
+
switch (_a.label) {
|
|
841
|
+
case 0:
|
|
842
|
+
_a.trys.push([0, 7, , 8]);
|
|
843
|
+
this.validateColor(options.filterColor);
|
|
844
|
+
jimpImage = void 0;
|
|
845
|
+
if (!options.imagePath.startsWith("http")) return [3 /*break*/, 3];
|
|
846
|
+
return [4 /*yield*/, this.imageConverter({
|
|
847
|
+
imagePath: options.imagePath,
|
|
848
|
+
newExtension: "png",
|
|
849
|
+
baseDir: options.baseDir !== null ? options.baseDir : undefined,
|
|
850
|
+
})];
|
|
851
|
+
case 1:
|
|
852
|
+
pngBuffer = _a.sent();
|
|
853
|
+
return [4 /*yield*/, jimp_1.read(pngBuffer)];
|
|
854
|
+
case 2:
|
|
855
|
+
jimpImage = _a.sent();
|
|
856
|
+
return [3 /*break*/, 5];
|
|
857
|
+
case 3:
|
|
858
|
+
if (!options.baseDir) {
|
|
859
|
+
throw new Error("You need to provide __dirname in options.");
|
|
860
|
+
}
|
|
861
|
+
imagePathResolved = options.baseDir
|
|
862
|
+
? path_1.resolve(options.baseDir, options.imagePath)
|
|
863
|
+
: options.imagePath;
|
|
864
|
+
return [4 /*yield*/, jimp_1.read(imagePathResolved)];
|
|
865
|
+
case 4:
|
|
866
|
+
jimpImage = _a.sent();
|
|
867
|
+
_a.label = 5;
|
|
868
|
+
case 5:
|
|
869
|
+
jimpImage.color([{ apply: "mix", params: [options.filterColor, 100] }]);
|
|
870
|
+
return [4 /*yield*/, jimpImage.getBufferAsync(jimp_1.MIME_PNG)];
|
|
871
|
+
case 6:
|
|
872
|
+
resultBuffer = _a.sent();
|
|
873
|
+
if (!Buffer.isBuffer(resultBuffer)) {
|
|
874
|
+
throw new Error("Unexpected result. Failed to apply color filter.");
|
|
875
|
+
}
|
|
876
|
+
return [2 /*return*/, resultBuffer];
|
|
877
|
+
case 7:
|
|
878
|
+
error_6 = _a.sent();
|
|
879
|
+
console.error("Error applying color filter:", error_6.message);
|
|
880
|
+
console.error(error_6.stack);
|
|
881
|
+
throw new Error("Failed to apply color filter");
|
|
882
|
+
case 8: return [2 /*return*/];
|
|
883
|
+
}
|
|
884
|
+
});
|
|
885
|
+
});
|
|
886
|
+
};
|
|
887
|
+
ApexPainter.prototype.bgRemoval = function (options) {
|
|
888
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
889
|
+
var apiKey, formData, lowerCaseImageUrl, response, errorCode, error_7;
|
|
890
|
+
return __generator(this, function (_a) {
|
|
891
|
+
switch (_a.label) {
|
|
892
|
+
case 0:
|
|
893
|
+
apiKey = options.apiKey;
|
|
894
|
+
formData = new form_data_1.default();
|
|
895
|
+
if (!apiKey) {
|
|
896
|
+
throw new Error("Error: No Api_Key was provided. We don't provide a default one.");
|
|
897
|
+
}
|
|
898
|
+
if (!options.imageUrl) {
|
|
899
|
+
throw new Error("Error: Please provide a valid image source (image_url).");
|
|
900
|
+
}
|
|
901
|
+
if (options.imageUrl.startsWith("https://media.discordapp.net/attachments/")) {
|
|
902
|
+
throw new Error("Error: Discord image URL isn't suppported at the moment.");
|
|
903
|
+
}
|
|
904
|
+
lowerCaseImageUrl = options.imageUrl.toLowerCase();
|
|
905
|
+
if (!lowerCaseImageUrl.endsWith(".png") &&
|
|
906
|
+
!lowerCaseImageUrl.endsWith(".jpg")) {
|
|
907
|
+
throw new Error("Error: Unsupported image format. Please provide a valid URL ending with .png or .jpg.");
|
|
908
|
+
}
|
|
909
|
+
formData.append("size", options.size || "auto");
|
|
910
|
+
formData.append("image_url", options.imageUrl);
|
|
911
|
+
formData.append("type_level", options.type_level || "latest");
|
|
912
|
+
formData.append("format", options.format || "auto");
|
|
913
|
+
formData.append("roi", options.roi || "0% 0% 100% 100%");
|
|
914
|
+
formData.append("crop", options.crop || false);
|
|
915
|
+
formData.append("crop_margin", options.crop_margin || "0");
|
|
916
|
+
formData.append("scale", options.scale || "original");
|
|
917
|
+
formData.append("position", options.position || "original");
|
|
918
|
+
formData.append("channels", options.channels || "rgba");
|
|
919
|
+
formData.append("add_shadow", options.add_shadow || false);
|
|
920
|
+
formData.append("semitransparency", options.semitransparency || true);
|
|
921
|
+
formData.append("bg_color", options.bg_color || null);
|
|
922
|
+
formData.append("bg_image_url", options.bg_image_url || null);
|
|
923
|
+
_a.label = 1;
|
|
924
|
+
case 1:
|
|
925
|
+
_a.trys.push([1, 3, , 4]);
|
|
926
|
+
return [4 /*yield*/, axios_1.default({
|
|
927
|
+
method: "post",
|
|
928
|
+
url: "https://api.remove.bg/v1.0/removebg",
|
|
929
|
+
data: formData,
|
|
930
|
+
responseType: "arraybuffer",
|
|
931
|
+
headers: __assign(__assign({}, formData.getHeaders()), { "X-Api-Key": apiKey }),
|
|
932
|
+
encoding: null,
|
|
933
|
+
})];
|
|
934
|
+
case 2:
|
|
935
|
+
response = _a.sent();
|
|
936
|
+
if (response.status !== 200) {
|
|
937
|
+
errorCode = response.status;
|
|
938
|
+
switch (errorCode) {
|
|
939
|
+
case 400:
|
|
940
|
+
console.error("Error 400: Invalid parameters or input file unprocessable (no credits charged)");
|
|
941
|
+
break;
|
|
942
|
+
case 402:
|
|
943
|
+
console.error("Error 402: Insufficient credits (no credits charged)");
|
|
944
|
+
break;
|
|
945
|
+
case 403:
|
|
946
|
+
console.error("Error 403: Authentication failed (no credits charged)");
|
|
947
|
+
break;
|
|
948
|
+
case 429:
|
|
949
|
+
console.error("Error 429: Rate limit exceeded (no credits charged)");
|
|
950
|
+
break;
|
|
951
|
+
default:
|
|
952
|
+
console.error("Error:", errorCode, response.statusText);
|
|
953
|
+
break;
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
else {
|
|
957
|
+
return [2 /*return*/, response.data];
|
|
958
|
+
}
|
|
959
|
+
return [3 /*break*/, 4];
|
|
960
|
+
case 3:
|
|
961
|
+
error_7 = _a.sent();
|
|
962
|
+
console.error("Request failed:", error_7.message);
|
|
963
|
+
return [3 /*break*/, 4];
|
|
964
|
+
case 4: return [2 /*return*/];
|
|
965
|
+
}
|
|
966
|
+
});
|
|
967
|
+
});
|
|
968
|
+
};
|
|
969
|
+
ApexPainter.prototype.createGIF = function (options) {
|
|
970
|
+
var _a, _b;
|
|
971
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
972
|
+
function resizeImage(image, targetWidth, targetHeight) {
|
|
973
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
974
|
+
var canvas, ctx;
|
|
975
|
+
return __generator(this, function (_a) {
|
|
976
|
+
canvas = (0, canvas_1.createCanvas)(targetWidth, targetHeight);
|
|
977
|
+
ctx = canvas.getContext("2d");
|
|
978
|
+
ctx.drawImage(image, 0, 0, targetWidth, targetHeight);
|
|
979
|
+
return [2 /*return*/, canvas];
|
|
980
|
+
});
|
|
981
|
+
});
|
|
982
|
+
}
|
|
983
|
+
function createOutputStream(outputFile) {
|
|
984
|
+
return fs_1.createWriteStream(outputFile);
|
|
985
|
+
}
|
|
986
|
+
function createBufferStream() {
|
|
987
|
+
var buffer = [];
|
|
988
|
+
var bufferStream = new stream_1.Writable({
|
|
989
|
+
write: function (chunk, encoding, next) {
|
|
990
|
+
buffer.push(chunk);
|
|
991
|
+
next();
|
|
992
|
+
},
|
|
993
|
+
});
|
|
994
|
+
bufferStream.getBuffer = function () {
|
|
995
|
+
return Buffer.concat(buffer);
|
|
996
|
+
};
|
|
997
|
+
return bufferStream;
|
|
998
|
+
}
|
|
999
|
+
function validateOptions(options) {
|
|
1000
|
+
if (options.outputFormat === "file" && !options.outputFile) {
|
|
1001
|
+
throw new Error("Output file path is required when using file output format.");
|
|
1002
|
+
}
|
|
1003
|
+
if (options.repeat !== undefined &&
|
|
1004
|
+
(typeof options.repeat !== "number" || options.repeat < 0)) {
|
|
1005
|
+
throw new Error("Repeat must be a non-negative number or undefined.");
|
|
1006
|
+
}
|
|
1007
|
+
if (options.quality !== undefined &&
|
|
1008
|
+
(typeof options.quality !== "number" ||
|
|
1009
|
+
options.quality < 1 ||
|
|
1010
|
+
options.quality > 20)) {
|
|
1011
|
+
throw new Error("Quality must be a number between 1 and 20 or undefined.");
|
|
1012
|
+
}
|
|
1013
|
+
if (options.canvasSize) {
|
|
1014
|
+
if (options.canvasSize.width !== undefined &&
|
|
1015
|
+
(!Number.isInteger(options.canvasSize.width) ||
|
|
1016
|
+
options.canvasSize.width <= 0)) {
|
|
1017
|
+
throw new Error("Canvas width must be a positive integer or undefined.");
|
|
1018
|
+
}
|
|
1019
|
+
if (options.canvasSize.height !== undefined &&
|
|
1020
|
+
(!Number.isInteger(options.canvasSize.height) ||
|
|
1021
|
+
options.canvasSize.height <= 0)) {
|
|
1022
|
+
throw new Error("Canvas height must be a positive integer or undefined.");
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
if (options.delay !== undefined &&
|
|
1026
|
+
(!Number.isInteger(options.delay) || options.delay <= 0)) {
|
|
1027
|
+
throw new Error("Delay must be a positive integer or undefined.");
|
|
1028
|
+
}
|
|
1029
|
+
if (options.watermark !== undefined &&
|
|
1030
|
+
typeof options.watermark !== "boolean") {
|
|
1031
|
+
throw new Error("Watermark must be a boolean or undefined.");
|
|
1032
|
+
}
|
|
1033
|
+
if (options.textOverlay !== undefined) {
|
|
1034
|
+
if (!options.textOverlay.text ||
|
|
1035
|
+
typeof options.textOverlay.text !== "string") {
|
|
1036
|
+
throw new Error("Text overlay text is required and must be a string.");
|
|
1037
|
+
}
|
|
1038
|
+
if (options.textOverlay.fontName !== undefined &&
|
|
1039
|
+
typeof options.textOverlay.fontName !== "string") {
|
|
1040
|
+
throw new Error("Text overlay fontName must be a string or undefined.");
|
|
1041
|
+
}
|
|
1042
|
+
if (options.textOverlay.fontPath !== undefined &&
|
|
1043
|
+
typeof options.textOverlay.fontPath !== "string") {
|
|
1044
|
+
throw new Error("Text overlay fontPath must be a string or undefined.");
|
|
1045
|
+
}
|
|
1046
|
+
if (options.textOverlay.fontSize !== undefined &&
|
|
1047
|
+
(!Number.isInteger(options.textOverlay.fontSize) ||
|
|
1048
|
+
options.textOverlay.fontSize <= 0)) {
|
|
1049
|
+
throw new Error("Text overlay fontSize must be a positive integer or undefined.");
|
|
1050
|
+
}
|
|
1051
|
+
if (options.textOverlay.fontColor !== undefined &&
|
|
1052
|
+
typeof options.textOverlay.fontColor !== "string") {
|
|
1053
|
+
throw new Error("Text overlay fontColor must be a string or undefined.");
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
function validateImageObject(imageObject) {
|
|
1058
|
+
return (imageObject &&
|
|
1059
|
+
typeof imageObject === "object" &&
|
|
1060
|
+
"source" in imageObject &&
|
|
1061
|
+
"isRemote" in imageObject);
|
|
1062
|
+
}
|
|
1063
|
+
function validateImages(images) {
|
|
1064
|
+
if (!Array.isArray(images)) {
|
|
1065
|
+
throw new Error('The "images" parameter must be an array.');
|
|
1066
|
+
}
|
|
1067
|
+
if (images.length === 0) {
|
|
1068
|
+
throw new Error('The "images" array must contain at least one image object.');
|
|
1069
|
+
}
|
|
1070
|
+
for (var _i = 0, images_1 = images; _i < images_1.length; _i++) {
|
|
1071
|
+
var imageObject = images_1[_i];
|
|
1072
|
+
if (!validateImageObject(imageObject)) {
|
|
1073
|
+
throw new Error('Each image object must have "source" and "isRemote" properties.');
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
var canvasWidth, canvasHeight, encoder, outputStream_1, canvas, ctx, _i, _c, imageInfo, image, _d, resizedImage, watermark, textOptions, fontPath, fontName, fontSize, fontColor, x, y, gifStream, e_1;
|
|
1078
|
+
return __generator(this, function (_e) {
|
|
1079
|
+
switch (_e.label) {
|
|
1080
|
+
case 0:
|
|
1081
|
+
_e.trys.push([0, 14, , 15]);
|
|
1082
|
+
validateOptions(options);
|
|
1083
|
+
validateImages(options.images);
|
|
1084
|
+
canvasWidth = ((_a = options.canvasSize) === null || _a === void 0 ? void 0 : _a.width) || 1200;
|
|
1085
|
+
canvasHeight = ((_b = options.canvasSize) === null || _b === void 0 ? void 0 : _b.height) || 1200;
|
|
1086
|
+
encoder = new gifencoder_1.default(canvasWidth, canvasHeight);
|
|
1087
|
+
outputStream_1 = options.outputFile
|
|
1088
|
+
? createOutputStream(options.outputFile)
|
|
1089
|
+
: createBufferStream();
|
|
1090
|
+
encoder.createReadStream().pipe(outputStream_1);
|
|
1091
|
+
encoder.start();
|
|
1092
|
+
encoder.setRepeat(options.repeat || 0);
|
|
1093
|
+
encoder.setQuality(options.quality || 10);
|
|
1094
|
+
encoder.setDelay(options.delay || 3000);
|
|
1095
|
+
canvas = (0, canvas_1.createCanvas)(canvasWidth, canvasHeight);
|
|
1096
|
+
ctx = canvas.getContext("2d");
|
|
1097
|
+
_i = 0, _c = options.images;
|
|
1098
|
+
_e.label = 1;
|
|
1099
|
+
case 1:
|
|
1100
|
+
if (!(_i < _c.length)) return [3 /*break*/, 10];
|
|
1101
|
+
imageInfo = _c[_i];
|
|
1102
|
+
if (!imageInfo.isRemote) return [3 /*break*/, 3];
|
|
1103
|
+
return [4 /*yield*/, (0, canvas_1.loadImage)(imageInfo.source)];
|
|
1104
|
+
case 2:
|
|
1105
|
+
_d = _e.sent();
|
|
1106
|
+
return [3 /*break*/, 5];
|
|
1107
|
+
case 3: return [4 /*yield*/, (0, canvas_1.loadImage)(imageInfo.source)];
|
|
1108
|
+
case 4:
|
|
1109
|
+
_d = _e.sent();
|
|
1110
|
+
_e.label = 5;
|
|
1111
|
+
case 5:
|
|
1112
|
+
image = _d;
|
|
1113
|
+
return [4 /*yield*/, resizeImage(image, canvasWidth, canvasHeight)];
|
|
1114
|
+
case 6:
|
|
1115
|
+
resizedImage = _e.sent();
|
|
1116
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
1117
|
+
ctx.drawImage(resizedImage, 0, 0);
|
|
1118
|
+
if (!options.watermark) return [3 /*break*/, 8];
|
|
1119
|
+
return [4 /*yield*/, (0, canvas_1.loadImage)("")];
|
|
1120
|
+
case 7:
|
|
1121
|
+
watermark = _e.sent();
|
|
1122
|
+
ctx.drawImage(watermark, 10, canvasHeight - watermark.height - 10);
|
|
1123
|
+
_e.label = 8;
|
|
1124
|
+
case 8:
|
|
1125
|
+
if (options.textOverlay) {
|
|
1126
|
+
textOptions = options.textOverlay;
|
|
1127
|
+
fontPath = textOptions.fontPath;
|
|
1128
|
+
fontName = textOptions.fontName || "Arial";
|
|
1129
|
+
fontSize = textOptions.fontSize || 20;
|
|
1130
|
+
fontColor = textOptions.fontColor || "white";
|
|
1131
|
+
x = textOptions.x || 10;
|
|
1132
|
+
y = textOptions.y || 30;
|
|
1133
|
+
if (fontPath) {
|
|
1134
|
+
canvas_1.GlobalFonts.registerFromPath(path_1.join(options.basDir || "", fontPath), fontName);
|
|
1135
|
+
}
|
|
1136
|
+
ctx.font = "".concat(fontSize, "px ").concat(fontName);
|
|
1137
|
+
ctx.fillStyle = fontColor;
|
|
1138
|
+
ctx.fillText(textOptions.text, x, y);
|
|
1139
|
+
}
|
|
1140
|
+
encoder.addFrame(ctx);
|
|
1141
|
+
_e.label = 9;
|
|
1142
|
+
case 9:
|
|
1143
|
+
_i++;
|
|
1144
|
+
return [3 /*break*/, 1];
|
|
1145
|
+
case 10:
|
|
1146
|
+
encoder.finish();
|
|
1147
|
+
outputStream_1.end();
|
|
1148
|
+
if (!(options.outputFormat === "file")) return [3 /*break*/, 12];
|
|
1149
|
+
if (!options.outputFile) {
|
|
1150
|
+
throw new Error("Please provide a valid file path");
|
|
1151
|
+
}
|
|
1152
|
+
return [4 /*yield*/, new Promise(function (resolve) { return outputStream_1.on("finish", resolve); })];
|
|
1153
|
+
case 11:
|
|
1154
|
+
_e.sent();
|
|
1155
|
+
console.log("GIF created successfully at ".concat(options.outputFile));
|
|
1156
|
+
return [3 /*break*/, 13];
|
|
1157
|
+
case 12:
|
|
1158
|
+
if (options.outputFormat === "base64") {
|
|
1159
|
+
outputStream_1.on("finish", function () {
|
|
1160
|
+
console.log("GIF created successfully");
|
|
1161
|
+
});
|
|
1162
|
+
return [2 /*return*/, outputStream_1.buffer.toString("base64")];
|
|
1163
|
+
}
|
|
1164
|
+
else if (options.outputFormat === "attachment") {
|
|
1165
|
+
outputStream_1.on("finish", function () {
|
|
1166
|
+
console.log("GIF created successfully");
|
|
1167
|
+
});
|
|
1168
|
+
gifStream = encoder.createReadStream();
|
|
1169
|
+
return [2 /*return*/, [{ attachment: gifStream, name: "gif.js" }]];
|
|
1170
|
+
}
|
|
1171
|
+
else if (options.outputFormat === "buffer") {
|
|
1172
|
+
outputStream_1.on("finish", function () {
|
|
1173
|
+
console.log("GIF created successfully");
|
|
1174
|
+
});
|
|
1175
|
+
return [2 /*return*/, outputStream_1.buffer];
|
|
1176
|
+
}
|
|
1177
|
+
else {
|
|
1178
|
+
throw new Error("Error: Please provide a valid format: 'buffer', 'base64', 'attachment',or 'output/file/path'.");
|
|
1179
|
+
}
|
|
1180
|
+
_e.label = 13;
|
|
1181
|
+
case 13: return [3 /*break*/, 15];
|
|
1182
|
+
case 14:
|
|
1183
|
+
e_1 = _e.sent();
|
|
1184
|
+
console.error(e_1);
|
|
1185
|
+
return [3 /*break*/, 15];
|
|
1186
|
+
case 15: return [2 /*return*/];
|
|
1187
|
+
}
|
|
1188
|
+
});
|
|
1189
|
+
});
|
|
1190
|
+
};
|
|
1191
|
+
return ApexPainter;
|
|
1192
|
+
}());
|
|
1193
|
+
|
|
1194
|
+
exports.ApexPainter = ApexPainter;
|