Recover sparse MAX sticker captures
This commit is contained in:
@@ -1452,9 +1452,81 @@ async function downloadDomStickerThroughScreenshot(p, request) {
|
|||||||
metrics.avgB > metrics.avgR + 45 &&
|
metrics.avgB > metrics.avgR + 45 &&
|
||||||
metrics.avgG > metrics.avgR + 30;
|
metrics.avgG > metrics.avgR + 30;
|
||||||
};
|
};
|
||||||
|
const stripMaxWallpaperFromStickerPng = async (buffer) => {
|
||||||
|
const base64 = buffer.toString("base64");
|
||||||
|
const strippedDataUrl = await p.evaluate(async (dataUrl) => {
|
||||||
|
const image = new Image();
|
||||||
|
image.src = dataUrl;
|
||||||
|
await image.decode();
|
||||||
|
|
||||||
|
const canvas = document.createElement("canvas");
|
||||||
|
canvas.width = image.naturalWidth;
|
||||||
|
canvas.height = image.naturalHeight;
|
||||||
|
const context = canvas.getContext("2d", { willReadFrequently: true });
|
||||||
|
if (!context || canvas.width <= 0 || canvas.height <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.drawImage(image, 0, 0);
|
||||||
|
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
|
||||||
|
const data = imageData.data;
|
||||||
|
let kept = 0;
|
||||||
|
|
||||||
|
for (let offset = 0; offset < data.length; offset += 4) {
|
||||||
|
const r = data[offset];
|
||||||
|
const g = data[offset + 1];
|
||||||
|
const b = data[offset + 2];
|
||||||
|
const a = data[offset + 3];
|
||||||
|
if (a <= 8) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const looksLikeMaxWallpaper = b > r + 25 &&
|
||||||
|
g > r + 20 &&
|
||||||
|
b > 150 &&
|
||||||
|
g > 130;
|
||||||
|
if (looksLikeMaxWallpaper) {
|
||||||
|
data[offset + 3] = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
kept++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kept < Math.max(80, Math.floor(canvas.width * canvas.height * 0.01))) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.putImageData(imageData, 0, 0);
|
||||||
|
return canvas.toDataURL("image/png");
|
||||||
|
}, `data:image/png;base64,${base64}`).catch(() => null);
|
||||||
|
|
||||||
|
const prefix = "data:image/png;base64,";
|
||||||
|
return typeof strippedDataUrl === "string" && strippedDataUrl.startsWith(prefix)
|
||||||
|
? Buffer.from(strippedDataUrl.slice(prefix.length), "base64")
|
||||||
|
: null;
|
||||||
|
};
|
||||||
|
const hasMeaningfulStickerContent = (metrics) => {
|
||||||
|
if (!metrics) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return metrics.opaqueRatio > 0.01 &&
|
||||||
|
(metrics.darkRatio > 0.01 ||
|
||||||
|
metrics.whiteRatio > 0.03 ||
|
||||||
|
metrics.cyanRatio < 0.5);
|
||||||
|
};
|
||||||
const stickerCaptureResult = async (buffer) => {
|
const stickerCaptureResult = async (buffer) => {
|
||||||
const metrics = await inspectStickerPng(buffer);
|
const metrics = await inspectStickerPng(buffer);
|
||||||
if (isMaxWallpaperCapture(metrics)) {
|
if (isMaxWallpaperCapture(metrics)) {
|
||||||
|
const stripped = await stripMaxWallpaperFromStickerPng(buffer);
|
||||||
|
if (stripped) {
|
||||||
|
const strippedMetrics = await inspectStickerPng(stripped);
|
||||||
|
if (!isMaxWallpaperCapture(strippedMetrics) && hasMeaningfulStickerContent(strippedMetrics)) {
|
||||||
|
return { contentType: "image/png", buffer: stripped };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
throw new Error(`${kindLabel} capture matched MAX chat wallpaper instead of sticker.`);
|
throw new Error(`${kindLabel} capture matched MAX chat wallpaper instead of sticker.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user