@pi-r/jimp 0.7.3 → 0.8.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/index.js +139 -75
- package/package.json +3 -3
- package/types/index.d.ts +21 -7
- package/util.js +8 -8
package/index.js
CHANGED
|
@@ -5,12 +5,13 @@ const child_process = require("child_process");
|
|
|
5
5
|
const jimp = require("jimp");
|
|
6
6
|
const gifwrap = require("gifwrap");
|
|
7
7
|
const bmp = require("bmp-js");
|
|
8
|
+
const crypto_1 = require("crypto");
|
|
8
9
|
const types_1 = require("@e-mc/types");
|
|
9
10
|
const Image = require('@e-mc/image');
|
|
10
11
|
let WEBPMUX = null, WEBPMUX_INIT = false;
|
|
11
12
|
try {
|
|
12
13
|
WEBPMUX = require('node-webpmux');
|
|
13
|
-
new WEBPMUX.Image().initLib().then(() => WEBPMUX_INIT = true);
|
|
14
|
+
void new WEBPMUX.Image().initLib().then(() => WEBPMUX_INIT = true);
|
|
14
15
|
}
|
|
15
16
|
catch {
|
|
16
17
|
}
|
|
@@ -80,9 +81,9 @@ function getMethodName(value) {
|
|
|
80
81
|
}
|
|
81
82
|
}
|
|
82
83
|
async function performCommand(host, instance, localUri, command, outputType, finalAs, buffer, parent) {
|
|
83
|
-
return jimp.read((buffer || localUri))
|
|
84
|
+
return await jimp.read((buffer || localUri))
|
|
84
85
|
.then(async (img) => {
|
|
85
|
-
return transformCommand(localUri, new JimpHandler(img, instance, host), command, outputType, finalAs, parent);
|
|
86
|
+
return await transformCommand(localUri, new JimpHandler(img, instance, host), command, outputType, finalAs, parent);
|
|
86
87
|
});
|
|
87
88
|
}
|
|
88
89
|
function execOptions(settings) {
|
|
@@ -117,19 +118,18 @@ async function transformCommand(localFile, handler, command, outputType, outputA
|
|
|
117
118
|
return handler;
|
|
118
119
|
case 1:
|
|
119
120
|
return handler.rotate();
|
|
120
|
-
default:
|
|
121
|
-
return handler.rotate(localFile, (err, result) => {
|
|
122
|
-
if (!err && handler.host?.moduleName === 'filemanager') {
|
|
123
|
-
try {
|
|
124
|
-
handler.host.add(result, parent);
|
|
125
|
-
}
|
|
126
|
-
catch {
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
121
|
}
|
|
122
|
+
return handler.rotate(localFile, (err, result) => {
|
|
123
|
+
if (!err && handler.host?.moduleName === 'filemanager') {
|
|
124
|
+
try {
|
|
125
|
+
handler.host.add(result, parent);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
131
|
}
|
|
132
|
-
function setImageCache(tempKey, tempFile, output, localFile) {
|
|
132
|
+
function setImageCache(instance, tempKey, tempFile, output, localFile) {
|
|
133
133
|
try {
|
|
134
134
|
if (typeof output === 'string') {
|
|
135
135
|
fs.copyFileSync(output, tempFile);
|
|
@@ -137,7 +137,7 @@ function setImageCache(tempKey, tempFile, output, localFile) {
|
|
|
137
137
|
else {
|
|
138
138
|
fs.writeFileSync(tempFile, output);
|
|
139
139
|
}
|
|
140
|
-
const stored = getCacheData
|
|
140
|
+
const stored = getCacheData(instance);
|
|
141
141
|
if (localFile) {
|
|
142
142
|
const { ctimeMs, mtimeMs, size } = fs.statSync(localFile);
|
|
143
143
|
stored[tempKey] = { tempKey, tempFile, ctimeMs, localFile, mtimeMs, size };
|
|
@@ -145,7 +145,7 @@ function setImageCache(tempKey, tempFile, output, localFile) {
|
|
|
145
145
|
else {
|
|
146
146
|
stored[tempKey] = { tempKey, tempFile, ctimeMs: Date.now() };
|
|
147
147
|
}
|
|
148
|
-
if (
|
|
148
|
+
if (instance.settings.jimp.cache_expires) {
|
|
149
149
|
fs.writeFile(tempFile + '.json', JSON.stringify(stored[tempKey]), 'utf-8', () => { });
|
|
150
150
|
}
|
|
151
151
|
}
|
|
@@ -153,8 +153,8 @@ function setImageCache(tempKey, tempFile, output, localFile) {
|
|
|
153
153
|
TEMP_DIR = '';
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
|
-
function getImageCache(tempKey) {
|
|
157
|
-
const stored = getCacheData
|
|
156
|
+
function getImageCache(instance, tempKey) {
|
|
157
|
+
const stored = getCacheData(instance);
|
|
158
158
|
const data = stored[tempKey];
|
|
159
159
|
if (data) {
|
|
160
160
|
const { tempFile, localFile, ctimeMs, mtimeMs, size } = data;
|
|
@@ -173,13 +173,13 @@ function getImageCache(tempKey) {
|
|
|
173
173
|
removeFile(tempFile);
|
|
174
174
|
delete stored[tempKey];
|
|
175
175
|
}
|
|
176
|
-
TEMP_DIR ||=
|
|
177
|
-
return [null, TEMP_DIR ? path.join(TEMP_DIR, (0,
|
|
176
|
+
TEMP_DIR ||= instance.getTempDir({ moduleDir: true, increment: 5 });
|
|
177
|
+
return [null, TEMP_DIR ? path.join(TEMP_DIR, (0, crypto_1.randomUUID)()) : ''];
|
|
178
178
|
}
|
|
179
|
-
function getCacheData() {
|
|
179
|
+
function getCacheData(instance) {
|
|
180
180
|
if (!CACHE_INIT) {
|
|
181
|
-
TEMP_DIR =
|
|
182
|
-
const settings =
|
|
181
|
+
TEMP_DIR = instance.getTempDir({ moduleDir: true, increment: 5 });
|
|
182
|
+
const settings = instance.settings.jimp ||= {};
|
|
183
183
|
const expires = (0, types_1.parseExpires)(settings.cache_expires || 0);
|
|
184
184
|
if (expires === 0) {
|
|
185
185
|
settings.cache_expires = 0;
|
|
@@ -189,10 +189,10 @@ function getCacheData() {
|
|
|
189
189
|
Image.removeDir(TEMP_DIR, true);
|
|
190
190
|
}
|
|
191
191
|
else {
|
|
192
|
-
const current = Date.now();
|
|
193
192
|
try {
|
|
193
|
+
const current = Date.now();
|
|
194
194
|
fs.readdirSync(TEMP_DIR, { withFileTypes: true }).forEach(item => {
|
|
195
|
-
if (item.isFile() && item.name
|
|
195
|
+
if (item.isFile() && path.extname(item.name) === '.json') {
|
|
196
196
|
const pathname = path.join(TEMP_DIR, item.name);
|
|
197
197
|
try {
|
|
198
198
|
const data = JSON.parse(fs.readFileSync(pathname, 'utf-8'));
|
|
@@ -218,19 +218,29 @@ function getCacheData() {
|
|
|
218
218
|
}
|
|
219
219
|
return CACHE_TRANSFORM;
|
|
220
220
|
}
|
|
221
|
-
function formatMessage(value, startTime, failed, cTimeMs) {
|
|
221
|
+
function formatMessage(instance, value, startTime, failed, cTimeMs) {
|
|
222
222
|
if (cTimeMs) {
|
|
223
|
-
|
|
223
|
+
instance.formatMessage(2048, "jimp", [value, 'cache'], new Date(cTimeMs).toLocaleString(), { ...Image.LOG_STYLE_NOTICE, hintBold: true });
|
|
224
224
|
}
|
|
225
225
|
else if (startTime) {
|
|
226
|
-
|
|
226
|
+
instance.writeTimeProcess("jimp", value, startTime, { type: 2048, failed });
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
|
-
function getTempPath(ext) {
|
|
230
|
-
const tempDir = TEMP_DIR ||
|
|
231
|
-
return path.join(tempDir, (0,
|
|
229
|
+
function getTempPath(instance, ext) {
|
|
230
|
+
const tempDir = TEMP_DIR || instance.getTempDir({ moduleDir: true, createDir: true }) || instance.getTempDir();
|
|
231
|
+
return path.join(tempDir, (0, crypto_1.randomUUID)() + '.' + ext);
|
|
232
232
|
}
|
|
233
|
-
|
|
233
|
+
function rotateAnim(cmd) {
|
|
234
|
+
const rotate = cmd.rotate;
|
|
235
|
+
if (rotate) {
|
|
236
|
+
rotate.values = [rotate.values.pop()];
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
function removeFile(pathname) {
|
|
240
|
+
fs.unlink(pathname, () => { });
|
|
241
|
+
}
|
|
242
|
+
const hasTransform = (cmd) => !!(cmd.rotate || cmd.opacity >= 0 && cmd.opacity < 1 || cmd.resize || cmd.crop || cmd.method);
|
|
243
|
+
const emptyResult = (options) => (options.tempFile ? '' : null);
|
|
234
244
|
class JimpHandler {
|
|
235
245
|
handler;
|
|
236
246
|
instance;
|
|
@@ -264,14 +274,18 @@ class JimpHandler {
|
|
|
264
274
|
const img = handler.clone().rotate(value);
|
|
265
275
|
const output = leading + value + ext;
|
|
266
276
|
tasks.push(img.writeAsync(output)
|
|
267
|
-
.then(() =>
|
|
268
|
-
|
|
277
|
+
.then(() => {
|
|
278
|
+
this.finalize(output, callback);
|
|
279
|
+
})
|
|
280
|
+
.catch((err) => {
|
|
281
|
+
this.instance.writeFail(["Unable to rotate image", "jimp"], err, 2048);
|
|
282
|
+
}));
|
|
269
283
|
}
|
|
270
284
|
}
|
|
271
285
|
if (deg) {
|
|
272
286
|
handler.rotate(deg);
|
|
273
287
|
}
|
|
274
|
-
if (tasks.length) {
|
|
288
|
+
if (tasks.length > 0) {
|
|
275
289
|
return Promise.all(tasks).then(() => this);
|
|
276
290
|
}
|
|
277
291
|
}
|
|
@@ -440,7 +454,11 @@ class JimpHandler {
|
|
|
440
454
|
else if (webp !== output) {
|
|
441
455
|
const tempFile = output;
|
|
442
456
|
queueMicrotask(() => {
|
|
443
|
-
fs.unlink(tempFile, error =>
|
|
457
|
+
fs.unlink(tempFile, error => {
|
|
458
|
+
if (!error) {
|
|
459
|
+
fs.rmdir(path.dirname(tempFile), () => { });
|
|
460
|
+
}
|
|
461
|
+
});
|
|
444
462
|
});
|
|
445
463
|
output = filename;
|
|
446
464
|
}
|
|
@@ -462,7 +480,7 @@ class JimpHandler {
|
|
|
462
480
|
}
|
|
463
481
|
async getBuffer(tempFile, saveAs) {
|
|
464
482
|
const empty = () => tempFile ? '' : null;
|
|
465
|
-
const output = getTempPath
|
|
483
|
+
const output = getTempPath(this.instance, this.instance.outputAs || (saveAs && util_1.MIME_OUTPUT.has('image/' + (saveAs === 'jpg' ? 'jpeg' : saveAs)) ? saveAs : this.handler.getMIME().split('/').pop()));
|
|
466
484
|
return !output ? empty() : new Promise(resolve => {
|
|
467
485
|
this.handler.write(output, error => {
|
|
468
486
|
if (error) {
|
|
@@ -484,7 +502,13 @@ class JimpHandler {
|
|
|
484
502
|
this.instance.writeFail(["Unable to read file", path.basename(result)], err, 32);
|
|
485
503
|
resolve(null);
|
|
486
504
|
}
|
|
487
|
-
|
|
505
|
+
finally {
|
|
506
|
+
fs.unlink(result, err => {
|
|
507
|
+
if (!err) {
|
|
508
|
+
this.instance.emit('file:delete', result);
|
|
509
|
+
}
|
|
510
|
+
});
|
|
511
|
+
}
|
|
488
512
|
}
|
|
489
513
|
});
|
|
490
514
|
});
|
|
@@ -541,7 +565,9 @@ class JimpHandler {
|
|
|
541
565
|
return;
|
|
542
566
|
}
|
|
543
567
|
return this.handler.writeAsync(output)
|
|
544
|
-
.then(() =>
|
|
568
|
+
.then(() => {
|
|
569
|
+
this.finalize(output, callback);
|
|
570
|
+
})
|
|
545
571
|
.catch((err) => {
|
|
546
572
|
if (callback) {
|
|
547
573
|
callback(err, '');
|
|
@@ -564,24 +590,23 @@ class JimpHandler {
|
|
|
564
590
|
class Jimp extends Image {
|
|
565
591
|
static async transform(file, command, options = {}) {
|
|
566
592
|
const [outputType, saveAs, finalAs] = (0, util_1.parseFormat)(command = command.trim(), options.mimeType);
|
|
567
|
-
const empty = () => options.tempFile ? '' : null;
|
|
568
593
|
if (!outputType) {
|
|
569
|
-
return
|
|
594
|
+
return emptyResult(options);
|
|
570
595
|
}
|
|
571
596
|
const instance = new Jimp(options.module);
|
|
572
597
|
let buffer = null;
|
|
573
598
|
if (Buffer.isBuffer(file)) {
|
|
574
599
|
const tempDir = TEMP_DIR || instance.getTempDir();
|
|
575
600
|
if (!this.createDir(tempDir)) {
|
|
576
|
-
return
|
|
601
|
+
return emptyResult(options);
|
|
577
602
|
}
|
|
578
603
|
try {
|
|
579
604
|
const { ext } = await this.resolveMime(file) || { ext: 'unknown' };
|
|
580
605
|
buffer = file;
|
|
581
|
-
fs.writeFileSync(file = path.join(tempDir, (0,
|
|
606
|
+
fs.writeFileSync(file = path.join(tempDir, (0, crypto_1.randomUUID)() + '.' + ext), buffer);
|
|
582
607
|
}
|
|
583
608
|
catch {
|
|
584
|
-
return
|
|
609
|
+
return emptyResult(options);
|
|
585
610
|
}
|
|
586
611
|
options.cache = false;
|
|
587
612
|
}
|
|
@@ -600,13 +625,13 @@ class Jimp extends Image {
|
|
|
600
625
|
}
|
|
601
626
|
const writeMessage = (failed, cTimeMs) => {
|
|
602
627
|
if (cTimeMs || options.startTime) {
|
|
603
|
-
formatMessage
|
|
628
|
+
formatMessage(instance, filename + (0, util_1.showOutputType)(options.mimeType, outputType, finalAs), options.startTime, failed, cTimeMs);
|
|
604
629
|
}
|
|
605
630
|
};
|
|
606
631
|
let tempKey, tempFile;
|
|
607
632
|
if (options.cache) {
|
|
608
633
|
let ctimeMs;
|
|
609
|
-
[buffer, tempFile, ctimeMs] = getImageCache
|
|
634
|
+
[buffer, tempFile, ctimeMs] = getImageCache(instance, tempKey = file + command + (options.mimeType || ''));
|
|
610
635
|
if (buffer) {
|
|
611
636
|
writeMessage(false, ctimeMs);
|
|
612
637
|
return buffer;
|
|
@@ -620,12 +645,18 @@ class Jimp extends Image {
|
|
|
620
645
|
instance.flushLog();
|
|
621
646
|
writeMessage(!result || instance.errors.length > 0);
|
|
622
647
|
if (result && tempKey && tempFile) {
|
|
623
|
-
setImageCache
|
|
648
|
+
setImageCache(instance, tempKey, tempFile, result, file);
|
|
624
649
|
}
|
|
625
650
|
return result;
|
|
626
651
|
})
|
|
627
|
-
.catch(() =>
|
|
628
|
-
|
|
652
|
+
.catch(() => {
|
|
653
|
+
return emptyResult(options);
|
|
654
|
+
})
|
|
655
|
+
.finally(() => {
|
|
656
|
+
if (buffer && !options.cache) {
|
|
657
|
+
removeFile(file);
|
|
658
|
+
}
|
|
659
|
+
});
|
|
629
660
|
}
|
|
630
661
|
_moduleName = "jimp";
|
|
631
662
|
_threadable = true;
|
|
@@ -697,13 +728,13 @@ class Jimp extends Image {
|
|
|
697
728
|
if (replace && file.localUri !== output && !host.assets.find(item => item.localUri === output && !item.invalid)) {
|
|
698
729
|
host.filesToRemove.add(output);
|
|
699
730
|
}
|
|
700
|
-
formatMessage
|
|
731
|
+
formatMessage(this, (0, util_1.showInputType)(mimeType, outputType, finalAs) + filename, startTime, false, ctimeMs);
|
|
701
732
|
resolve();
|
|
702
733
|
};
|
|
703
734
|
let tempKey, tempFile;
|
|
704
735
|
if (this.settings.cache && (file.etag || file.buffer)) {
|
|
705
736
|
let buffer, ctimeMs;
|
|
706
|
-
[buffer, tempFile] = getImageCache
|
|
737
|
+
[buffer, tempFile] = getImageCache(this, tempKey = (file.etag || Image.asHash(file.buffer)) + command + mimeType);
|
|
707
738
|
if (buffer) {
|
|
708
739
|
const result = finalAs === 'webp' ? (0, util_1.renameExt)(output, 'webp', replace) : output;
|
|
709
740
|
fs.writeFileSync(result, file.buffer = buffer);
|
|
@@ -713,7 +744,7 @@ class Jimp extends Image {
|
|
|
713
744
|
}
|
|
714
745
|
const finalize = (value) => {
|
|
715
746
|
if (tempFile && tempKey) {
|
|
716
|
-
setImageCache
|
|
747
|
+
setImageCache(this, tempKey, tempFile, value);
|
|
717
748
|
}
|
|
718
749
|
if (replace) {
|
|
719
750
|
delete file.buffer;
|
|
@@ -737,8 +768,10 @@ class Jimp extends Image {
|
|
|
737
768
|
const frame = new GifFrame(img.handler.bitmap);
|
|
738
769
|
GifUtil.quantizeSorokin(frame, 256);
|
|
739
770
|
GifUtil.write(output, [frame])
|
|
740
|
-
.then(() =>
|
|
741
|
-
|
|
771
|
+
.then(() => {
|
|
772
|
+
finalize(output);
|
|
773
|
+
})
|
|
774
|
+
.catch(errorResponse);
|
|
742
775
|
}
|
|
743
776
|
catch (err) {
|
|
744
777
|
errorResponse(err);
|
|
@@ -764,14 +797,9 @@ class Jimp extends Image {
|
|
|
764
797
|
this.writeFail(["Unable to convert file", path.basename(localUri)], err, { type: 2048, startTime });
|
|
765
798
|
resolve();
|
|
766
799
|
};
|
|
767
|
-
const
|
|
768
|
-
|
|
769
|
-
if (rotate) {
|
|
770
|
-
rotate.values = [rotate.values.pop()];
|
|
771
|
-
}
|
|
800
|
+
const startMessage = () => {
|
|
801
|
+
host.formatMessage(2048, "jimp", ["Transforming image...", path.basename(localUri)], command);
|
|
772
802
|
};
|
|
773
|
-
const hasTransform = (cmd) => !!(cmd.rotate || cmd.opacity >= 0 && cmd.opacity < 1 || cmd.resize || cmd.crop || cmd.method);
|
|
774
|
-
const startMessage = () => host.formatMessage(2048, "jimp", ["Transforming image...", path.basename(localUri)], command);
|
|
775
803
|
if (mimeType === jimp.MIME_GIF) {
|
|
776
804
|
if (outputType === jimp.MIME_GIF || outputType === "image/webp") {
|
|
777
805
|
const cmd = this.parseCommand(command);
|
|
@@ -857,19 +885,34 @@ class Jimp extends Image {
|
|
|
857
885
|
return transformCommand(localUri, handler, cmd, jimp.MIME_GIF);
|
|
858
886
|
}))
|
|
859
887
|
.then(items => {
|
|
888
|
+
const quantize = this.settings.jimp?.gifwrap_quantize || '';
|
|
860
889
|
const frames = gif.frames;
|
|
861
890
|
for (let i = 0, length = items.length; i < length; ++i) {
|
|
862
891
|
const img = new BitmapImage(items[i].handler.bitmap);
|
|
863
|
-
|
|
892
|
+
switch (quantize) {
|
|
893
|
+
case 'none':
|
|
894
|
+
break;
|
|
895
|
+
case 'dekker':
|
|
896
|
+
GifUtil.quantizeDekker(img, 256);
|
|
897
|
+
break;
|
|
898
|
+
case 'wu':
|
|
899
|
+
GifUtil.quantizeWu(img, 256);
|
|
900
|
+
break;
|
|
901
|
+
default:
|
|
902
|
+
GifUtil.quantizeSorokin(img, 256);
|
|
903
|
+
break;
|
|
904
|
+
}
|
|
864
905
|
frames[i].bitmap = img.bitmap;
|
|
865
906
|
}
|
|
866
907
|
GifUtil.write(output, frames, gif)
|
|
867
|
-
.then(() =>
|
|
868
|
-
|
|
908
|
+
.then(() => {
|
|
909
|
+
transformWebP(output, true);
|
|
910
|
+
})
|
|
911
|
+
.catch(errorResponse);
|
|
869
912
|
})
|
|
870
|
-
.catch(
|
|
913
|
+
.catch(errorResponse);
|
|
871
914
|
})
|
|
872
|
-
.catch(
|
|
915
|
+
.catch(errorResponse);
|
|
873
916
|
}
|
|
874
917
|
catch (err) {
|
|
875
918
|
errorResponse(err);
|
|
@@ -909,16 +952,31 @@ class Jimp extends Image {
|
|
|
909
952
|
if (outputType === jimp.MIME_GIF) {
|
|
910
953
|
try {
|
|
911
954
|
const { GifFrame, GifUtil, BitmapImage } = gifwrap;
|
|
955
|
+
const quantize = this.settings.jimp?.gifwrap_quantize || '';
|
|
912
956
|
const frames = new Array(length);
|
|
913
957
|
for (let i = 0; i < length; ++i) {
|
|
914
958
|
const { x, y, delay } = webp.frames[i];
|
|
915
959
|
const img = new BitmapImage(items[i].handler.bitmap);
|
|
916
|
-
|
|
960
|
+
switch (quantize) {
|
|
961
|
+
case 'none':
|
|
962
|
+
break;
|
|
963
|
+
case 'dekker':
|
|
964
|
+
GifUtil.quantizeDekker(img, 256);
|
|
965
|
+
break;
|
|
966
|
+
case 'wu':
|
|
967
|
+
GifUtil.quantizeWu(img, 256);
|
|
968
|
+
break;
|
|
969
|
+
default:
|
|
970
|
+
GifUtil.quantizeSorokin(img, 256);
|
|
971
|
+
break;
|
|
972
|
+
}
|
|
917
973
|
frames[i] = new GifFrame(new BitmapImage(img), { xOffset: x, yOffset: y, delayCentisecs: delay / 10 });
|
|
918
974
|
}
|
|
919
975
|
GifUtil.write(output, frames, { loops: webp.anim.loops })
|
|
920
|
-
.then(() =>
|
|
921
|
-
|
|
976
|
+
.then(() => {
|
|
977
|
+
finalize(output);
|
|
978
|
+
})
|
|
979
|
+
.catch(errorResponse);
|
|
922
980
|
}
|
|
923
981
|
catch (err) {
|
|
924
982
|
errorResponse(err);
|
|
@@ -940,13 +998,15 @@ class Jimp extends Image {
|
|
|
940
998
|
Promise.all(frames)
|
|
941
999
|
.then(() => {
|
|
942
1000
|
webp.save(output, { width: w, height: h, bgColor: cmd.rotate ? [0, 0, 0, 0] : undefined })
|
|
943
|
-
.then(() =>
|
|
944
|
-
|
|
1001
|
+
.then(() => {
|
|
1002
|
+
finalize(output);
|
|
1003
|
+
})
|
|
1004
|
+
.catch(errorResponse);
|
|
945
1005
|
})
|
|
946
|
-
.catch(
|
|
1006
|
+
.catch(errorResponse);
|
|
947
1007
|
}
|
|
948
1008
|
})
|
|
949
|
-
.catch(
|
|
1009
|
+
.catch(errorResponse);
|
|
950
1010
|
}
|
|
951
1011
|
else {
|
|
952
1012
|
resolve();
|
|
@@ -966,7 +1026,7 @@ class Jimp extends Image {
|
|
|
966
1026
|
};
|
|
967
1027
|
const settings = this.settings;
|
|
968
1028
|
const { path: webp_path } = settings.webp ||= {};
|
|
969
|
-
const bmpFile = getTempPath
|
|
1029
|
+
const bmpFile = getTempPath(this, 'bmp');
|
|
970
1030
|
try {
|
|
971
1031
|
child_process.execFile((0, util_1.getWebP_bin)('dwebp', webp_path), [(0, util_1.normalizePath)(localUri), '-bmp', '-o', (0, util_1.normalizePath)(bmpFile)], { shell: true, signal: this.signal, ...execOptions(settings) }, err => {
|
|
972
1032
|
if (!err) {
|
|
@@ -974,7 +1034,11 @@ class Jimp extends Image {
|
|
|
974
1034
|
}
|
|
975
1035
|
else {
|
|
976
1036
|
removeFile(bmpFile);
|
|
977
|
-
tryWebpMux().then(valid =>
|
|
1037
|
+
void tryWebpMux().then(valid => {
|
|
1038
|
+
if (!valid) {
|
|
1039
|
+
errorResponse(err);
|
|
1040
|
+
}
|
|
1041
|
+
});
|
|
978
1042
|
}
|
|
979
1043
|
});
|
|
980
1044
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-r/jimp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "Jimp image constructor for E-mc.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"publishConfig": {
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"homepage": "https://github.com/anpham6/pi-r#readme",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@e-mc/image": "^0.
|
|
24
|
-
"@e-mc/types": "^0.
|
|
23
|
+
"@e-mc/image": "^0.10.0",
|
|
24
|
+
"@e-mc/types": "^0.10.0",
|
|
25
25
|
"bmp-js": "^0.1.0",
|
|
26
26
|
"gifwrap": "^0.10.1",
|
|
27
27
|
"jimp": "^0.22.12"
|
package/types/index.d.ts
CHANGED
|
@@ -1,10 +1,24 @@
|
|
|
1
|
-
import type { IHost, IImage, ImageConstructor } from '@e-mc/types/lib';
|
|
2
|
-
import type {
|
|
1
|
+
import type { IFileManager, IHost, IImage, ImageConstructor } from '@e-mc/types/lib';
|
|
2
|
+
import type { ExternalAsset } from '@e-mc/types/lib/asset';
|
|
3
|
+
import type { TransformOptions } from '@e-mc/types/lib/image';
|
|
4
|
+
import type { ImageModule, ImageSettings } from '@e-mc/types/lib/settings';
|
|
5
|
+
import type { ExecAction } from '@e-mc/types/lib/module';
|
|
3
6
|
|
|
4
7
|
import type { ImageHandler } from '@e-mc/image/types';
|
|
5
8
|
|
|
6
9
|
import type * as jimp from 'jimp';
|
|
7
10
|
|
|
11
|
+
export interface JimpSettings extends ImageSettings {
|
|
12
|
+
jimp?: {
|
|
13
|
+
exec?: ExecAction;
|
|
14
|
+
cache_expires?: number | string;
|
|
15
|
+
rotate_clockwise?: boolean;
|
|
16
|
+
gifwrap_quantize?: "dekker" | "sorokin" | "wu" | "none";
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type ResultCallback<T = unknown, U = void, V = unknown> = (err: V, result: T) => U;
|
|
21
|
+
|
|
8
22
|
export interface IJimpHandler<T extends IHost = IHost, U extends ImageModule = ImageModule> extends ImageHandler<jimp, T, IImage<T, U>> {
|
|
9
23
|
method(): Promise<void>;
|
|
10
24
|
rotate(localFile?: string, callback?: ResultCallback<string>): Promise<this>;
|
|
@@ -12,8 +26,8 @@ export interface IJimpHandler<T extends IHost = IHost, U extends ImageModule = I
|
|
|
12
26
|
writeAsync(output: string, callback?: ResultCallback): Promise<void>;
|
|
13
27
|
}
|
|
14
28
|
|
|
15
|
-
export interface JimpImageConstructor extends ImageConstructor {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
29
|
+
export interface JimpImageConstructor<T extends IFileManager<U>, U extends ExternalAsset = ExternalAsset, V extends ImageModule = ImageModule<JimpSettings>> extends ConstructorDerived<ImageConstructor<T, V>> {
|
|
30
|
+
transform<W extends TransformOptions>(file: string, command: string, options?: W): Promise<W extends { tempFile: true } ? string : Null<Buffer>>;
|
|
31
|
+
readonly prototype: IImage<T, V>;
|
|
32
|
+
new(module?: V, ...args: unknown[]): IImage<T, V>;
|
|
33
|
+
}
|
package/util.js
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
exports.
|
|
2
|
+
exports.MIME_OUTPUT = exports.MIME_INPUT = void 0;
|
|
3
|
+
exports.parseFormat = parseFormat;
|
|
4
|
+
exports.renameExt = renameExt;
|
|
5
|
+
exports.normalizePath = normalizePath;
|
|
6
|
+
exports.getWebP_bin = getWebP_bin;
|
|
7
|
+
exports.showInputType = showInputType;
|
|
8
|
+
exports.showOutputType = showOutputType;
|
|
3
9
|
const path = require("path");
|
|
4
10
|
const fs = require("fs");
|
|
5
11
|
const jimp = require("jimp");
|
|
@@ -52,7 +58,6 @@ function parseFormat(command, mimeType, gif) {
|
|
|
52
58
|
}
|
|
53
59
|
return ['', '', ''];
|
|
54
60
|
}
|
|
55
|
-
exports.parseFormat = parseFormat;
|
|
56
61
|
function renameExt(output, ext, replace) {
|
|
57
62
|
let result = (0, types_1.renameExt)(output.replace('.__copy__.', '.'), ext);
|
|
58
63
|
if (!replace) {
|
|
@@ -64,31 +69,26 @@ function renameExt(output, ext, replace) {
|
|
|
64
69
|
}
|
|
65
70
|
return result;
|
|
66
71
|
}
|
|
67
|
-
exports.renameExt = renameExt;
|
|
68
72
|
function normalizePath(value) {
|
|
69
73
|
return '"' + value.replace(/"/g, '\\"') + '"';
|
|
70
74
|
}
|
|
71
|
-
exports.normalizePath = normalizePath;
|
|
72
75
|
function getWebP_bin(name, pathname) {
|
|
73
76
|
if (pathname && fs.existsSync(pathname)) {
|
|
74
|
-
name +=
|
|
77
|
+
name += Image.PLATFORM_WIN32 ? '.exe' : '';
|
|
75
78
|
const bin = path.join(pathname, name);
|
|
76
79
|
return Image.sanitizeCmd(fs.existsSync(bin) ? bin : path.join(pathname, 'bin', name));
|
|
77
80
|
}
|
|
78
81
|
return require(name + '-bin');
|
|
79
82
|
}
|
|
80
|
-
exports.getWebP_bin = getWebP_bin;
|
|
81
83
|
function showInputType(value, outputType, finalAs) {
|
|
82
84
|
if (finalAs) {
|
|
83
85
|
outputType = 'image/' + finalAs;
|
|
84
86
|
}
|
|
85
87
|
return value && outputType !== value ? value.split('/').pop() + ' -> ' : '';
|
|
86
88
|
}
|
|
87
|
-
exports.showInputType = showInputType;
|
|
88
89
|
function showOutputType(value, outputType, finalAs) {
|
|
89
90
|
if (finalAs) {
|
|
90
91
|
outputType = 'image/' + finalAs;
|
|
91
92
|
}
|
|
92
93
|
return value !== outputType ? ' -> ' + outputType.split('/').pop() : '';
|
|
93
94
|
}
|
|
94
|
-
exports.showOutputType = showOutputType;
|