-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.mjs
125 lines (107 loc) Β· 3.55 KB
/
index.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import { webkit } from "playwright";
import { fileTypeFromBuffer } from "file-type";
import sharp from "sharp";
const browser = await webkit.launch(),
logger = console.log;
async function newLaunch() {
let page = await browser.newPage();
await page.goto("https://illuminarty.ai/en/illuminate");
return page;
}
/**
* @param {Buffer} imageBuffer - Image buffer
* @param {number} maxSize - Max size
*/
async function compressImage(imageBuffer, maxSize) {
if (imageBuffer.length <= maxSize) {
return [imageBuffer, 0];
}
let compressedImageBuffer = imageBuffer,
compressedSize = imageBuffer.length,
minQuality = 50,
maxQuality = 100,
resQuality;
while (compressedSize > maxSize) {
const quality = Math.floor((minQuality + maxQuality) / 2),
image = sharp(compressedImageBuffer);
compressedImageBuffer = await image
.jpeg({ quality })
.toBuffer()
.catch((error) => {
throw new Error(`Error compressing image: ${error}`);
});
compressedSize = compressedImageBuffer.length;
if (compressedSize > maxSize) {
minQuality = quality + 1;
} else {
maxQuality = quality;
}
if (minQuality == maxQuality) {
minQuality = 1;
maxQuality = 50;
}
resQuality = quality;
}
return [compressedImageBuffer, resQuality];
}
/**
* Scan an image.
* @param {Buffer} img - Image buffer to scan.
* @param {Object} [options] - {Optional} Optional args.
* @param {string} [options.mime] - {Optional} MIME type of the Image, will use magic numbers instead if not specified.
* @param {boolean} [options.v] - {Optional} Debug logging.
* @param {number} [options.timeout] - {Optional} Custom timeout, by default the function will throw after 60 seconds if page doesn't load.
* @returns {Promise<number>} Probability of AI-generation.
*/
async function scan(img, options) {
if (!options) options = {};
const v = options.v,
mime = options.mime,
timeout = options.timeout || 60000,
ftime = performance.now();
if (v) logger(`Config: ${v}, ${mime}, ${timeout}`);
if (v) logger("Launching page...");
const page = await newLaunch();
if (v) logger("Launched");
if (v) logger("Determining MIME type");
let type = mime ? mime : (await fileTypeFromBuffer(img)).mime;
if (v) logger("MIME type: " + type);
if (!["jpg", "jpeg", "png", "webp", "jfif"].includes(type.split("/")[1]))
throw new Error("MIME type unsupported!");
if (v) logger("Waiting for input selector...");
await page.waitForSelector("#inputfile", {
state: "attached",
timeout: timeout,
});
if (v) logger("Input is open.");
if (v) logger("Preprocessing image if needed...");
img = compressImage(img, 3 * 1024 * 1024);
if (v) logger("Processed.");
if (v) logger("Loading image...");
await page.locator("#inputfile").setInputFiles({
name: "img." + type.split("/")[1],
mimeType: type,
buffer: img,
});
if (v) logger("Loaded!");
if (v) logger("Waiting for server to process...");
await page.waitForSelector(
"body > div.container > div:nth-child(3) > p > strong",
{ state: "attached" }
);
if (v) logger("Done.");
if (v) logger("Grabbing elem.");
let result = (
await page
.locator("body > div.container > div:nth-child(3) > p > strong")
.innerText()
).replace("%", "");
if (v) logger("Grabbed.");
if (v) logger("Closing page...");
await page.close();
if (v) logger("Closed.");
const stime = Math.floor((performance.now() - ftime) / 1000);
if (v) logger("Exec took: " + stime.toString() + "s");
return Number(result);
}
export { scan };