This commit is contained in:
CrazyboyQCD 2025-09-02 11:12:17 +08:00 committed by GitHub
commit 918b92f5ab
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 23 additions and 9 deletions

View file

@ -24,6 +24,7 @@ export const overlayCache = new LRUCache<string, any>(500);
export const imageDecodeCache = new LRUCache<string, HTMLImageElement>(64); export const imageDecodeCache = new LRUCache<string, HTMLImageElement>(64);
export const paletteDetectionCache = new LRUCache<string, boolean>(200); export const paletteDetectionCache = new LRUCache<string, boolean>(200);
export const baseMinifyCache = new LRUCache<string, ImageData>(100); export const baseMinifyCache = new LRUCache<string, ImageData>(100);
export const colorCaches = new LRUCache<string, Map<number, [number, number, number]>>(500);
export const tooLargeOverlays = new Set<string>(); export const tooLargeOverlays = new Set<string>();
export function clearOverlayCache() { export function clearOverlayCache() {
@ -31,5 +32,6 @@ export function clearOverlayCache() {
imageDecodeCache.clear(); imageDecodeCache.clear();
paletteDetectionCache.clear(); paletteDetectionCache.clear();
baseMinifyCache.clear(); baseMinifyCache.clear();
colorCaches.clear();
tooLargeOverlays.clear(); tooLargeOverlays.clear();
} }

View file

@ -42,11 +42,10 @@ function findClosestColorIndex(r: number, g: number, b: number) {
let index = 0; let index = 0;
for (let i = 0; i < ALL_COLORS.length; i++) { for (let i = 0; i < ALL_COLORS.length; i++) {
const color = ALL_COLORS[i]; const color = ALL_COLORS[i];
const distance = Math.sqrt( const distance =
Math.pow(r - color[0], 2) + Math.pow(r - color[0], 2) +
Math.pow(g - color[1], 2) + Math.pow(g - color[1], 2) +
Math.pow(b - color[2], 2) Math.pow(b - color[2], 2);
);
if (distance < minDistance) { if (distance < minDistance) {
minDistance = distance; minDistance = distance;
index = i; index = i;

View file

@ -1,7 +1,8 @@
/// <reference types="tampermonkey" /> /// <reference types="tampermonkey" />
import { WPLACE_FREE, WPLACE_PAID, WPLACE_NAMES, DEFAULT_FREE_KEYS } from '../core/palette'; import { WPLACE_FREE, WPLACE_PAID, WPLACE_NAMES, DEFAULT_FREE_KEYS } from '../core/palette';
import { createCanvas } from '../core/canvas'; import { createCanvas } from '../core/canvas';
import { config, saveConfig } from '../core/store'; import { colorCaches } from '../core/cache';
import { config, saveConfig, type OverlayItem } from '../core/store';
import { MAX_OVERLAY_DIM } from '../core/constants'; import { MAX_OVERLAY_DIM } from '../core/constants';
import { ensureHook } from '../core/hook'; import { ensureHook } from '../core/hook';
import { clearOverlayCache, paletteDetectionCache } from '../core/cache'; import { clearOverlayCache, paletteDetectionCache } from '../core/cache';
@ -38,7 +39,7 @@ type CCState = {
selectedPaid: Set<string>; selectedPaid: Set<string>;
realtime: boolean; realtime: boolean;
overlay: any | null; overlay: OverlayItem | null;
lastColorCounts: Record<string, number>; lastColorCounts: Record<string, number>;
isStale: boolean; isStale: boolean;
}; };
@ -191,7 +192,7 @@ export function buildCCModal() {
renderPaletteGrid(); renderPaletteGrid();
} }
export function openCCModal(overlay: any) { export function openCCModal(overlay: OverlayItem) {
if (!cc) return; if (!cc) return;
cc.overlay = overlay; cc.overlay = overlay;
@ -233,7 +234,7 @@ function closeCCModal() {
} }
function weightedNearest(r: number, g: number, b: number, palette: number[][]) { function weightedNearest(r: number, g: number, b: number, palette: number[][]) {
let best: number[] | null = null, bestDist = Infinity; let best: [number, number, number] | null = null, bestDist = Infinity;
for (let i = 0; i < palette.length; i++) { for (let i = 0; i < palette.length; i++) {
const [pr, pg, pb] = palette[i]; const [pr, pg, pb] = palette[i];
const rmean = (pr + r) / 2; const rmean = (pr + r) / 2;
@ -243,7 +244,7 @@ function weightedNearest(r: number, g: number, b: number, palette: number[][]) {
const x = (512 + rmean) * rdiff * rdiff >> 8; const x = (512 + rmean) * rdiff * rdiff >> 8;
const y = 4 * gdiff * gdiff; const y = 4 * gdiff * gdiff;
const z = (767 - rmean) * bdiff * bdiff >> 8; const z = (767 - rmean) * bdiff * bdiff >> 8;
const dist = Math.sqrt(x + y + z); const dist = x + y + z;
if (dist < bestDist) { bestDist = dist; best = [pr, pg, pb]; } if (dist < bestDist) { bestDist = dist; best = [pr, pg, pb]; }
} }
return best || [0,0,0]; return best || [0,0,0];
@ -266,11 +267,23 @@ function processImage() {
const palette = getActivePalette(); const palette = getActivePalette();
const counts: Record<string, number> = {}; const counts: Record<string, number> = {};
const id = cc.overlay.id;
let colorCache = colorCaches.get(id);
if (!colorCache) {
colorCache = new Map();
colorCaches.set(id, colorCache);
}
for (let i = 0; i < src.length; i += 4) { for (let i = 0; i < src.length; i += 4) {
const r = src[i], g = src[i+1], b = src[i+2], a = src[i+3]; const r = src[i], g = src[i+1], b = src[i+2], a = src[i+3];
if (a === 0) { out[i]=0; out[i+1]=0; out[i+2]=0; out[i+3]=0; continue; } if (a === 0) { out[i]=0; out[i+1]=0; out[i+2]=0; out[i+3]=0; continue; }
const [nr, ng, nb] = palette.length ? weightedNearest(r,g,b,palette) : [r,g,b]; const color = (r<<24)|(g<<16)|(b<<8)|a;
let cached = colorCache.get(color);
if (!cached) {
cached = palette.length ? weightedNearest(r,g,b,palette) : [r,g,b];
colorCache.set(color, cached);
}
const [nr, ng, nb] = cached;
out[i]=nr; out[i+1]=ng; out[i+2]=nb; out[i+3]=255; out[i]=nr; out[i+1]=ng; out[i+2]=nb; out[i+3]=255;
const key = `${nr},${ng},${nb}`; const key = `${nr},${ng},${nb}`;
counts[key] = (counts[key] || 0) + 1; counts[key] = (counts[key] || 0) + 1;