@shibam/sticker-maker 1.2.6 → 1.2.7
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/package.json +2 -1
- package/utils/convert.js +20 -47
- package/test/gif-image.gif +0 -0
- package/test/index.js +0 -11
- package/test/lol.mp4 +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shibam/sticker-maker",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.7",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"file-type": "^20.0.0",
|
|
16
16
|
"jimp": "^1.6.0",
|
|
17
17
|
"node-webpmux": "^3.2.0",
|
|
18
|
+
"sharp": "0.30.0",
|
|
18
19
|
"webp-converter": "^2.3.3"
|
|
19
20
|
}
|
|
20
21
|
}
|
package/utils/convert.js
CHANGED
|
@@ -4,14 +4,14 @@ import { promises as fs } from "fs";
|
|
|
4
4
|
import { tmpdir } from "os";
|
|
5
5
|
import { join } from "path";
|
|
6
6
|
import { fileTypeFromBuffer } from "file-type";
|
|
7
|
-
|
|
7
|
+
import sharp from "sharp";
|
|
8
8
|
|
|
9
9
|
const exec = promisify(execCallback);
|
|
10
10
|
|
|
11
11
|
export default class MediaConverter {
|
|
12
12
|
constructor(options = {}) {
|
|
13
13
|
this.fps = options.fps || 12;
|
|
14
|
-
this.quality = options.quality ||
|
|
14
|
+
this.quality = options.quality || 10;
|
|
15
15
|
this.width = options.width || 512;
|
|
16
16
|
this.mime = null;
|
|
17
17
|
}
|
|
@@ -24,11 +24,11 @@ export default class MediaConverter {
|
|
|
24
24
|
|
|
25
25
|
if (this.mime.startsWith("video/")) {
|
|
26
26
|
const gif = await this.videoToGif(buffer);
|
|
27
|
-
return await this.
|
|
27
|
+
return await this.ToWebp(gif);
|
|
28
28
|
} else if (this.mime === "image/gif") {
|
|
29
|
-
return await this.
|
|
29
|
+
return await this.ToWebp(buffer);
|
|
30
30
|
} else if (this.mime.startsWith("image/")) {
|
|
31
|
-
return await this.
|
|
31
|
+
return await this.ToWebp(buffer);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
throw new Error(`Unsupported file type: ${this.mime}`);
|
|
@@ -55,51 +55,24 @@ export default class MediaConverter {
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
async
|
|
59
|
-
const tempInput = join(tmpdir(), `input_${Date.now()}.gif`);
|
|
60
|
-
const tempOutput = join(tmpdir(), `output_${Date.now()}.webp`);
|
|
61
|
-
|
|
62
|
-
try {
|
|
63
|
-
await fs.writeFile(tempInput, buffer);
|
|
64
|
-
|
|
65
|
-
// Use gif2webp to convert GIF to WebP
|
|
66
|
-
const gif2webpCmd = `gif2webp "${tempInput}" -q ${this.quality} -o "${tempOutput}"`;
|
|
67
|
-
await exec(gif2webpCmd);
|
|
58
|
+
async ToWebp(buffer) {
|
|
68
59
|
|
|
69
|
-
|
|
60
|
+
const mimeType = this.mime;
|
|
61
|
+
const isAnimated = mimeType?.includes("video") || mimeType?.includes("gif");
|
|
70
62
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
return webpBuffer;
|
|
74
|
-
} catch (error) {
|
|
75
|
-
await Promise.all([fs.unlink(tempInput).catch(() => {}), fs.unlink(tempOutput).catch(() => {})]);
|
|
76
|
-
throw new Error(`Failed to convert gif to webp: ${error.message}`);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
63
|
+
// Initialize sharp with animation support for GIFs or video frames
|
|
64
|
+
const res = sharp(buffer, { animated: isAnimated });
|
|
79
65
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
66
|
+
// Resize image to fit within the specified width while preserving aspect ratio
|
|
67
|
+
res.resize(this.width, this.width, {
|
|
68
|
+
fit: sharp.fit.contain,
|
|
69
|
+
background: { r: 0, g: 0, b: 0, alpha: 0 }, // Transparent background
|
|
70
|
+
});
|
|
83
71
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
const cwebpCmd = `cwebp "${tempInput}" -q ${this.quality} -o "${tempOutput}"`;
|
|
90
|
-
await exec(cwebpCmd);
|
|
91
|
-
|
|
92
|
-
// Read the resulting WebP file as a buffer
|
|
93
|
-
const webpBuffer = await fs.readFile(tempOutput);
|
|
94
|
-
|
|
95
|
-
// Clean up temporary files
|
|
96
|
-
await Promise.all([fs.unlink(tempInput).catch(() => {}), fs.unlink(tempOutput).catch(() => {})]);
|
|
97
|
-
|
|
98
|
-
return webpBuffer; // Return the WebP buffer as output
|
|
99
|
-
} catch (error) {
|
|
100
|
-
// Clean up temporary files in case of error
|
|
101
|
-
await Promise.all([fs.unlink(tempInput).catch(() => {}), fs.unlink(tempOutput).catch(() => {})]);
|
|
102
|
-
throw new Error(`Failed to convert image to webp: ${error.message}`);
|
|
103
|
-
}
|
|
72
|
+
// Convert to WebP format with the specified quality
|
|
73
|
+
return await res
|
|
74
|
+
.toFormat("webp")
|
|
75
|
+
.webp({ quality: this.quality, lossless: isAnimated }) // Lossless for GIFs or animations
|
|
76
|
+
.toBuffer();
|
|
104
77
|
}
|
|
105
78
|
}
|
package/test/gif-image.gif
DELETED
|
Binary file
|
package/test/index.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import Sticker from '../index.js';
|
|
2
|
-
import * as fs from 'fs';
|
|
3
|
-
const sticker = new Sticker('./test/lol.mp4',{
|
|
4
|
-
pack: 'My Pack',
|
|
5
|
-
author: 'Me',
|
|
6
|
-
category: ['😹'],
|
|
7
|
-
quality: 80,
|
|
8
|
-
text: 'Hello World'
|
|
9
|
-
});
|
|
10
|
-
sticker.metadata().then(console.log);
|
|
11
|
-
fs.writeFileSync('sticker.webp', await sticker.build());
|
package/test/lol.mp4
DELETED
|
Binary file
|