From 395d326eda426d963d4089e23494d5a0ec6bb410 Mon Sep 17 00:00:00 2001 From: Zylan Date: Fri, 25 Apr 2025 11:42:40 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=A2=9C=E8=89=B2=E6=98=A0?= =?UTF-8?q?=E5=B0=84=E9=80=BB=E8=BE=91=EF=BC=8C=E6=94=B9=E4=B8=BA=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E4=B8=BB=E5=AF=BC=E9=A2=9C=E8=89=B2=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=A0=BC=E9=A2=9C=E8=89=B2=E8=AE=A1=E7=AE=97?= =?UTF-8?q?=EF=BC=8C=E6=8F=90=E5=8D=87=E9=A2=9C=E8=89=B2=E5=87=86=E7=A1=AE?= =?UTF-8?q?=E6=80=A7=E5=92=8C=E5=A4=84=E7=90=86=E6=95=88=E7=8E=87=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/page.tsx | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/app/page.tsx b/src/app/page.tsx index 1d37c12..825c056 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -300,12 +300,11 @@ export default function Home() { let processedCells = 0; const initialMappedData: { key: string; color: string }[][] = Array(M).fill(null).map(() => Array(N).fill({ key: t1FallbackColor.key, color: t1FallbackColor.hex })); - // --- First Loop: Map Colors and Data (using average color) --- + // --- First Loop: Map Colors and Data (using DOMINANT color) --- for (let j = 0; j < M; j++) { for (let i = 0; i < N; i++) { const startXOriginal = Math.floor(i * cellWidthOriginal); const startYOriginal = Math.floor(j * cellHeightOriginal); - // Ensure we don't go past image bounds due to flooring/ceiling const endXOriginal = Math.min(img.width, Math.ceil((i + 1) * cellWidthOriginal)); const endYOriginal = Math.min(img.height, Math.ceil((j + 1) * cellHeightOriginal)); const currentCellWidth = Math.max(1, endXOriginal - startXOriginal); @@ -318,30 +317,44 @@ export default function Home() { catch (e) { console.error(`Failed getImageData at (${i},${j}):`, e); continue; } const data = imageData.data; - let sumR = 0, sumG = 0, sumB = 0, pixelCount = 0; + // ++ Use an object to count color frequencies ++ + const colorCountsInCell: { [key: string]: number } = {}; + let dominantColorRgb: { r: number; g: number; b: number } | null = null; + let maxCount = 0; + let totalPixelCount = 0; // Count valid pixels in the cell + // ++ Count frequency of each color ++ for (let p = 0; p < data.length; p += 4) { if (data[p + 3] < 128) continue; // Ignore transparent/semi-transparent pixels - sumR += data[p]; - sumG += data[p + 1]; - sumB += data[p + 2]; - pixelCount++; + const r = data[p]; + const g = data[p + 1]; + const b = data[p + 2]; + const colorKey = `${r},${g},${b}`; + colorCountsInCell[colorKey] = (colorCountsInCell[colorKey] || 0) + 1; + totalPixelCount++; + + // ++ Keep track of the dominant color found so far ++ + if (colorCountsInCell[colorKey] > maxCount) { + maxCount = colorCountsInCell[colorKey]; + dominantColorRgb = { r, g, b }; + } } let finalCellColorData: { key: string; color: string }; - if (pixelCount > 0) { - const avgRgb = { r: Math.round(sumR / pixelCount), g: Math.round(sumG / pixelCount), b: Math.round(sumB / pixelCount) }; - const closestBead = findClosestPaletteColor(avgRgb, currentPalette); + // ++ Map based on dominant color if found, else use fallback ++ + if (totalPixelCount > 0 && dominantColorRgb) { + const closestBead = findClosestPaletteColor(dominantColorRgb, currentPalette); finalCellColorData = { key: closestBead.key, color: closestBead.hex }; } else { + // Use fallback if cell was empty or only contained transparent pixels finalCellColorData = { key: t1FallbackColor.key, color: t1FallbackColor.hex }; } - initialMappedData[j][i] = finalCellColorData; + initialMappedData[j][i] = finalCellColorData; // Store in initial data processedCells++; } } - console.log(`Initial data mapping complete. Processed ${processedCells} cells. Starting region merging...`); + console.log(`Initial data mapping complete (using dominant cell color). Processed ${processedCells} cells. Starting region merging...`); // --- Region Merging Step ---