1
0
forked from noxious/client

Added web worker to improve tile analysis performance

This commit is contained in:
2025-02-01 03:11:13 +01:00
parent 09ee9bf01d
commit ac1396304f
4 changed files with 205 additions and 95 deletions

View File

@ -0,0 +1,64 @@
import type { TileAnalysisResult } from '@/types/tileTypes'
const PIXEL_SAMPLE_RATE = 4
self.onmessage = async (e: MessageEvent) => {
const { imageData, tileId, tileName } = e.data
const result = analyzeTile(imageData, tileId, tileName)
self.postMessage(result)
}
function analyzeTile(imageData: ImageData, tileId: string, tileName: string): TileAnalysisResult {
const { r, g, b } = getDominantColorFast(imageData)
const edge = getEdgeComplexityFast(imageData)
const namePrefix = tileName.split('_')[0]
return {
tileId,
color: { r, g, b },
edge,
namePrefix
}
}
function getDominantColorFast(imageData: ImageData) {
const data = new Uint8ClampedArray(imageData.data.buffer)
let r = 0, g = 0, b = 0, total = 0
const length = data.length
for (let i = 0; i < length; i += 4 * PIXEL_SAMPLE_RATE) {
if (data[i + 3] > 0) {
r += data[i]
g += data[i + 1]
b += data[i + 2]
total++
}
}
return total > 0 ? {
r: Math.round(r / total),
g: Math.round(g / total),
b: Math.round(b / total)
} : { r: 0, g: 0, b: 0 }
}
function getEdgeComplexityFast(imageData: ImageData) {
const data = new Uint8ClampedArray(imageData.data.buffer)
const width = imageData.width
const height = imageData.height
let edgePixels = 0
for (let y = 0; y < height; y += PIXEL_SAMPLE_RATE) {
for (let x = 0; x < width; x += PIXEL_SAMPLE_RATE) {
const i = (y * width + x) * 4
if (data[i + 3] > 0 && (
x === 0 || y === 0 || x >= width - PIXEL_SAMPLE_RATE || y >= height - PIXEL_SAMPLE_RATE ||
data[i - 4 * PIXEL_SAMPLE_RATE + 3] === 0 || data[i + 4 * PIXEL_SAMPLE_RATE + 3] === 0 ||
data[i - width * 4 * PIXEL_SAMPLE_RATE + 3] === 0 || data[i + width * 4 * PIXEL_SAMPLE_RATE + 3] === 0
)) {
edgePixels++
}
}
}
return edgePixels * PIXEL_SAMPLE_RATE
}