koishi-plugin-memesluna 0.4.2 → 0.4.3
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/lib/index.js +41 -23
- package/package.json +6 -3
package/lib/index.js
CHANGED
|
@@ -64,15 +64,6 @@ function hashImageBuffer(buffer) {
|
|
|
64
64
|
return (0, import_crypto.createHash)("sha256").update(buffer).digest("hex");
|
|
65
65
|
}
|
|
66
66
|
__name(hashImageBuffer, "hashImageBuffer");
|
|
67
|
-
function loadJimp() {
|
|
68
|
-
try {
|
|
69
|
-
const jimpModule = require("jimp");
|
|
70
|
-
return jimpModule.Jimp || jimpModule.default?.Jimp || null;
|
|
71
|
-
} catch {
|
|
72
|
-
return null;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
__name(loadJimp, "loadJimp");
|
|
76
67
|
function loadOptionalSharp() {
|
|
77
68
|
try {
|
|
78
69
|
const packageName = "sharp";
|
|
@@ -96,6 +87,40 @@ __name(countHexBitDistance, "countHexBitDistance");
|
|
|
96
87
|
var DHASH_BITS = 64;
|
|
97
88
|
var DHASH_WIDTH = 9;
|
|
98
89
|
var DHASH_HEIGHT = 8;
|
|
90
|
+
function decodeImagePixels(buffer) {
|
|
91
|
+
try {
|
|
92
|
+
if (buffer.length >= 8 && buffer.readUInt32BE(0) === 2303741511 && buffer.readUInt32BE(4) === 218765834) {
|
|
93
|
+
const png = require("pngjs").PNG.sync.read(buffer);
|
|
94
|
+
return { data: png.data, width: png.width, height: png.height };
|
|
95
|
+
}
|
|
96
|
+
if (buffer.length >= 3 && buffer[0] === 255 && buffer[1] === 216 && buffer[2] === 255) {
|
|
97
|
+
const jpeg = require("jpeg-js").decode(buffer, { useTArray: true });
|
|
98
|
+
return { data: jpeg.data, width: jpeg.width, height: jpeg.height };
|
|
99
|
+
}
|
|
100
|
+
if (buffer.length >= 6 && buffer.toString("ascii", 0, 3) === "GIF") {
|
|
101
|
+
const { GifReader } = require("omggif");
|
|
102
|
+
const reader = new GifReader(buffer);
|
|
103
|
+
const data = Buffer.alloc(reader.width * reader.height * 4);
|
|
104
|
+
reader.decodeAndBlitFrameRGBA(0, data);
|
|
105
|
+
return { data, width: reader.width, height: reader.height };
|
|
106
|
+
}
|
|
107
|
+
if (buffer.length >= 2 && buffer[0] === 66 && buffer[1] === 77) {
|
|
108
|
+
const bmp = require("bmp-js").decode(buffer);
|
|
109
|
+
const data = Buffer.alloc(bmp.width * bmp.height * 4);
|
|
110
|
+
for (let i = 0; i < bmp.data.length; i += 4) {
|
|
111
|
+
data[i] = bmp.data[i + 3];
|
|
112
|
+
data[i + 1] = bmp.data[i + 2];
|
|
113
|
+
data[i + 2] = bmp.data[i + 1];
|
|
114
|
+
data[i + 3] = bmp.data[i];
|
|
115
|
+
}
|
|
116
|
+
return { data, width: bmp.width, height: bmp.height };
|
|
117
|
+
}
|
|
118
|
+
} catch {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
__name(decodeImagePixels, "decodeImagePixels");
|
|
99
124
|
function lumaFromRgba(data, offset) {
|
|
100
125
|
const alpha = data[offset + 3] / 255;
|
|
101
126
|
const r = data[offset] * alpha + 255 * (1 - alpha);
|
|
@@ -357,22 +382,15 @@ var MemesLunaService = class extends import_koishi.Service {
|
|
|
357
382
|
await this.backfillImageFingerprints();
|
|
358
383
|
}
|
|
359
384
|
async getImagePerceptualHash(buffer) {
|
|
360
|
-
const
|
|
361
|
-
if (
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
const samples = [];
|
|
367
|
-
for (let y = 0; y < DHASH_HEIGHT; y++) {
|
|
368
|
-
for (let x = 0; x < DHASH_WIDTH; x++) {
|
|
369
|
-
samples.push(averageCellLuma(data, width, height, x, y));
|
|
370
|
-
}
|
|
385
|
+
const decoded = decodeImagePixels(buffer);
|
|
386
|
+
if (decoded) {
|
|
387
|
+
const samples = [];
|
|
388
|
+
for (let y = 0; y < DHASH_HEIGHT; y++) {
|
|
389
|
+
for (let x = 0; x < DHASH_WIDTH; x++) {
|
|
390
|
+
samples.push(averageCellLuma(decoded.data, decoded.width, decoded.height, x, y));
|
|
371
391
|
}
|
|
372
|
-
return buildDhashFromLumaGrid(samples);
|
|
373
|
-
} catch (error) {
|
|
374
|
-
this.ctx.logger("memesluna").debug(`Jimp failed to calculate perceptual hash: ${error.message}`);
|
|
375
392
|
}
|
|
393
|
+
return buildDhashFromLumaGrid(samples);
|
|
376
394
|
}
|
|
377
395
|
const sharp = loadOptionalSharp();
|
|
378
396
|
if (!sharp) return "";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koishi-plugin-memesluna",
|
|
3
3
|
"description": "Image Forward service for Koishi with ChatLuna integration",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.3",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
7
7
|
"types": "lib/index.d.ts",
|
|
@@ -41,9 +41,12 @@
|
|
|
41
41
|
"node": ">=18.0.0"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"
|
|
44
|
+
"bmp-js": "^0.1.0",
|
|
45
|
+
"jpeg-js": "^0.4.4",
|
|
45
46
|
"koishi-plugin-chatluna": "^1.3.0-alpha.49",
|
|
46
|
-
"koishi-plugin-chatluna-storage-service": "^1.0.6"
|
|
47
|
+
"koishi-plugin-chatluna-storage-service": "^1.0.6",
|
|
48
|
+
"omggif": "^1.0.10",
|
|
49
|
+
"pngjs": "^7.0.0"
|
|
47
50
|
},
|
|
48
51
|
"devDependencies": {
|
|
49
52
|
"@koishijs/client": "^5.30.11",
|