diff --git a/README.md b/README.md index 46b12ca..80647ea 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ 杂色问题的产生,是因为没有进行颜色合并操作,需要从未访问单元格开始,使用BFS 查找欧氏距离小于阈值的邻近单元格,形成区域。将整个区域统一设置为该区域内出现次数最多的色号对应的颜色即可。 ### 3️⃣ 背景移除 -无法进行拼豆数量统计的原因,是没有进行背景移除操作:先定义背景色号列表。从图像所有边界单元格开始执行洪水填充。将所有与边界连通且颜色属于背景色号列表的单元格标记为“外部”。统计和下载时将忽略这些“外部”单元格即可。 +无法进行拼豆数量统计的原因,是没有进行背景移除操作:先定义背景色号列表。从图像所有边界单元格开始执行洪水填充。将所有与边界连通且颜色属于背景色号列表的单元格标记为"外部"。统计和下载时将忽略这些"外部"单元格即可。 ### 4️⃣ 颜色排除与重映射 这是杂色自动去除仍不干净的情况下的附加功能,首先确定图像处理后最初包含的所有已存在颜色。重映射时,仅在已存在颜色中排除和其他已排除颜色的子集里寻找替换色。 @@ -112,7 +112,7 @@ ### 调色板数据 -预设的拼豆调色板数据定义在 `src/app/beadPaletteData.json` 文件中。不同的色板组合 (如 168色、96色等) 在 `src/app/page.tsx` 的 `paletteOptions` 中定义。 +预设的拼豆调色板数据定义在 `src/app/colorSystemMapping.json` 文件中,该文件包含了所有颜色的hex值到各个色号系统(MARD、COCO、漫漫、盼盼、咪小窝)的映射关系。不同的色板组合 (如 168色、96色等) 在 `src/app/page.tsx` 的 `paletteOptions` 中定义。 ## 本地开发 diff --git a/src/app/beadPaletteData.json b/src/app/beadPaletteData.json deleted file mode 100644 index 4763e14..0000000 --- a/src/app/beadPaletteData.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "ZG1": "#DAABB3", "B16": "#C5ED9C", "D4": "#182A84", "F3": "#F74941", "H6": "#2F2B2F", "P17": "#FEA324", - "ZG2": "#D6AA87", "B17": "#9BB13A", "D5": "#B843C5", "F4": "#FC283C", "H7": "#000000", "P18": "#FEB89F", - "ZG3": "#C1BD8D", "B18": "#E6EE49", "D6": "#AC7BDE", "F5": "#E7002F", "H8": "#E7D6DB", "P19": "#FFFEEC", - "ZG4": "#96869F", "B19": "#24B88C", "D7": "#8854B3", "F6": "#943630", "H9": "#EDEDED", "P20": "#FEBECF", - "ZG5": "#8490A6", "B20": "#C2F0CC", "D8": "#E2D3FF", "F7": "#971937", "H10": "#EEE9EA", "P21": "#ECBEBF", - "ZG6": "#94BFE2", "B21": "#156A6B", "D9": "#D5B9F8", "F8": "#BC0028", "H11": "#CECDD5", "P22": "#E4A89F", - "ZG7": "#E2A9D2", "B22": "#0B3C43", "D10": "#361851", "F9": "#E2677A", "H12": "#FFF5ED", "P23": "#A56268", - "ZG8": "#AB91C0", "B23": "#303A21", "D11": "#B9BAE1", "F10": "#8A4526", "H13": "#F5ECD2", "Q1": "#F2A5E8", - "A1": "#FAF4C8", "B24": "#EEFCA5", "D12": "#DE9AD4", "F11": "#5A2121", "H14": "#CFD7D3", "Q2": "#E9EC91", - "A2": "#FFFFD5", "B25": "#4E846D", "D13": "#B90095", "F12": "#FD4E6A", "H15": "#98A6A8", "Q3": "#FFFF00", - "A3": "#FEFF8B", "B26": "#8D7A35", "D14": "#8B279B", "F13": "#F35744", "H16": "#1D1414", "Q4": "#FFEBFA", - "A4": "#FBED56", "B27": "#CCE1AF", "D15": "#2F1F90", "F14": "#FFA9AD", "H17": "#F1EDED", "Q5": "#76CEDE", - "A5": "#F4D738", "B28": "#9EE5B9", "D16": "#E3E1EE", "F15": "#D30022", "H18": "#FFFDF0", "R1": "#D50D21", - "A6": "#FEAC4C", "B29": "#C5E254", "D17": "#C4D4F6", "F16": "#FEC2A6", "H19": "#F6EFE2", "R2": "#F92F83", - "A7": "#FE8B4C", "B30": "#E2FCB1", "D18": "#A45EC7", "F17": "#E69C79", "H20": "#949FA3", "R3": "#FD8324", - "A8": "#FFDA45", "B31": "#B0E792", "D19": "#D8C3D7", "F18": "#D37C46", "H21": "#FFFBE1", "R4": "#F8EC31", - "A9": "#FF995B", "B32": "#9CAB5A", "D20": "#9C32B2", "F19": "#C1444A", "H22": "#CACAD4", "R5": "#35C75B", - "A10": "#F77C31", "C1": "#E8FFE7", "D21": "#9A009B", "F20": "#CD9391", "H23": "#9A9D94", "R6": "#238891", - "A11": "#FFDD99", "C2": "#A9F9FC", "D22": "#333A95", "F21": "#F7B4C6", "M1": "#BCC6B8", "R7": "#19779D", - "A12": "#FE9F72", "C3": "#A0E2FB", "D23": "#EBDAFC", "F22": "#FDC0D0", "M2": "#8AA386", "R8": "#1A60C3", - "A13": "#FFC365", "C4": "#41CCFF", "D24": "#7786E5", "F23": "#F67E66", "M3": "#697D80", "R9": "#9A56B4", - "A14": "#FD543D", "C5": "#01ACEB", "D25": "#494FC7", "F24": "#E698AA", "M4": "#E3D2BC", "R10": "#FFDB4C", - "A15": "#FFF365", "C6": "#50AAF0", "D26": "#DFC2F8", "F25": "#E54B4F", "M5": "#D0CCAA", "R11": "#FFEBFA", - "A16": "#FFFF9F", "C7": "#3677D2", "E1": "#FDD3CC", "G1": "#FFE2CE", "M6": "#B0A782", "R12": "#D8D5CE", - "A17": "#FFE36E", "C8": "#0F54C0", "E2": "#FEC0DF", "G2": "#FFC4AA", "M7": "#B4A497", "R13": "#55514C", - "A18": "#FEBE7D", "C9": "#324BCA", "E3": "#FFB7E7", "G3": "#F4C3A5", "M8": "#B38281", "R14": "#9FE4DF", - "A19": "#FD7C72", "C10": "#3EBCE2", "E4": "#E8649E", "G4": "#E1B383", "M9": "#A58767", "R15": "#77CEE9", - "A20": "#FFD568", "C11": "#28DDDE", "E5": "#F551A2", "G5": "#EDB045", "M10": "#C5B2BC", "R16": "#3ECFCA", - "A21": "#FFE395", "C12": "#1C334D", "E6": "#F13D74", "G6": "#E99C17", "M11": "#9F7594", "R17": "#4A867A", - "A22": "#F4F57D", "C13": "#CDE8FF", "E7": "#C63478", "G7": "#9D5B3E", "M12": "#644749", "R18": "#7FCD9D", - "A23": "#E6C9B7", "C14": "#D5FDFF", "E8": "#FFDBE9", "G8": "#753832", "M13": "#D19066", "R19": "#CDE55D", - "A24": "#F7F8A2", "C15": "#22C4C6", "E9": "#E970CC", "G9": "#E6B483", "M14": "#C77362", "R20": "#E8C7B4", - "A25": "#FFD67D", "C16": "#1557A8", "E10": "#D33793", "G10": "#D98C39", "M15": "#757D78", "R21": "#AD6F3C", - "A26": "#FFC830", "C17": "#04D1F6", "E11": "#FCDDD2", "G11": "#E0C593", "P1": "#FCF7F8", "R22": "#6C372F", - "B1": "#E6EE31", "C18": "#1D3344", "E12": "#F78FC3", "G12": "#FFC890", "P2": "#B0A9AC", "R23": "#FEB872", - "B2": "#63F347", "C19": "#1887A2", "E13": "#B5006D", "G13": "#B7714A", "P3": "#AFDCAB", "R24": "#F3C1C0", - "B3": "#9EF780", "C20": "#176DAF", "E14": "#FFD1BA", "G14": "#8D614C", "P4": "#FEA49F", "R25": "#C9675E", - "B4": "#5DE035", "C21": "#BEDDFF", "E15": "#F8C7C9", "G15": "#FCF9E0", "P5": "#EE8C3E", "R26": "#D293BE", - "B5": "#35E352", "C22": "#67B4BE", "E16": "#FFF3EB", "G16": "#F2D9BA", "P6": "#5FD0A7", "R27": "#EA8CB1", - "B6": "#65E2A6", "C23": "#C8E2FF", "E17": "#FFE2EA", "G17": "#78524B", "P7": "#EB9270", "R28": "#9C87D6", - "B7": "#3DAF80", "C24": "#7CC4FF", "E18": "#FFC7DB", "G18": "#FFE4CC", "P8": "#F0D958", "T1": "#FFFFFF", - "B8": "#1C9C4F", "C25": "#A9E5E5", "E19": "#FEBAD5", "G19": "#E07935", "P9": "#D9D9D9", "Y1": "#FD6FB4", - "B9": "#27523A", "C26": "#3CAED8", "E20": "#D8C7D1", "G20": "#A94023", "P10": "#D9C7EA", "Y2": "#FEB481", - "B10": "#95D3C2", "C27": "#D3DFFA", "E21": "#BD9DA1", "G21": "#B88558", "P11": "#F3ECC9", "Y3": "#D7FAA0", - "B11": "#5D722A", "C28": "#BBCFED", "E22": "#B785A1", "H1": "#FDFBFF", "H2": "#FEFFFF", "P12": "#E6EEF2", "Y4": "#8BDBFA", - "B12": "#166F41", "C29": "#34488E", "E23": "#937A8D", "H3": "#B6B1BA", "P13": "#AACBEF", "Y5": "#E987EA", - "B13": "#CAEB7B", "D1": "#AEB4F2", "E24": "#E1BCE8", "H4": "#89858C", "P14": "#337680", - "B14": "#ADE946", "D2": "#858EDD", "F1": "#FD957B", "H5": "#48464E", "P15": "#668575", - "B15": "#2E5132", "D3": "#2F54AF", "F2": "#FC3D46", "P16": "#FEBF45" -} \ No newline at end of file diff --git a/src/app/page.tsx b/src/app/page.tsx index 12b6715..27f6a56 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -20,12 +20,11 @@ import { GridDownloadOptions } from '../types/downloadTypes'; import DownloadSettingsModal, { gridLineColorOptions } from '../components/DownloadSettingsModal'; import { downloadImage } from '../utils/imageDownloader'; -import beadPaletteData from './beadPaletteData.json'; import { colorSystemOptions, convertPaletteToColorSystem, - getDisplayColorKey, getColorKeyByHex, + getMardToHexMapping, ColorSystem } from '../utils/colorSystemUtils'; @@ -63,48 +62,19 @@ function sortColorKeys(a: string, b: string): number { } // --- Define available palette key sets --- -const allPaletteKeys = Object.keys(beadPaletteData); +// 从colorSystemMapping.json获取所有MARD色号 +const mardToHexMapping = getMardToHexMapping(); -// 144 Color Palette Keys -const palette144Keys = ["A1", "B1", "C1", "D1", "E1", "F1", "G1", "H1", "M1", "A2", "B2", "C2", "D2", "E2", "F2", "G2", "H2", "M2", "A3", "B3", "C3", "D3", "E3", "F3", "G3", "H3", "M3", "A4", "B4", "C4", "D5", "E4", "F4", "G4", "H4", "M4", "A5", "B5", "C5", "D6", "E5", "F5", "G5", "H5", "M5", "A6", "B6", "C6", "D7", "E6", "F6", "G6", "H6", "M6", "A7", "B7", "C7", "D8", "E7", "F7", "G7", "H7", "M7", "A8", "B8", "C8", "D9", "E8", "F8", "G8", "H8", "M8", "A9", "B10", "C9", "D11", "E9", "F9", "G9", "H9", "M9", "A10", "B11", "C10", "D12", "E10", "F10", "G10", "H10", "M10", "A11", "B12", "C11", "D13", "E11", "F11", "G11", "H11", "M11", "A12", "B13", "C13", "D14", "E12", "F12", "G12", "H12", "M12", "A13", "B14", "C14", "D15", "E13", "F13", "G13", "H13", "M13", "A14", "B15", "C15", "D16", "E14", "F14", "G14", "H14", "M14", "A15", "B16", "C16", "D17", "E15", "G15", "M15", "B17", "C17", "D18", "G16", "B18", "D19", "G17", "B19", "D20", "B20", "D21", "T1"]; // Ensure T1 is present - -// 168 Color Palette Keys (from user table) -const palette168Keys = ["A1", "B1", "C1", "D1", "E1", "F1", "G1", "M1", "A2", "B2", "C2", "D2", "E2", "F2", "G2", "H2", "M2", "A3", "B3", "C3", "D3", "E3", "F3", "G3", "H3", "M3", "A4", "B4", "C4", "D5", "E4", "F4", "G4", "H4", "M4", "A5", "B5", "C5", "D6", "E5", "F5", "G5", "H5", "M5", "A6", "B6", "C6", "D7", "E6", "F6", "G6", "H6", "M6", "A7", "B7", "C7", "D8", "E7", "F7", "G7", "H7", "M7", "A8", "B8", "C8", "D9", "E8", "F8", "G8", "H8", "M8", "A9", "B10", "C9", "D11", "E9", "F9", "G9", "H9", "M9", "A10", "B11", "C10", "D12", "E10", "F10", "G10", "H10", "M10", "A11", "B12", "C11", "D13", "E11", "F11", "G11", "H11", "M11", "A12", "B13", "C13", "D14", "E12", "F12", "G12", "H12", "M12", "A13", "B14", "C14", "D15", "E13", "F13", "G13", "H13", "M13", "A14", "B15", "C15", "D16", "E14", "F14", "G14", "H14", "M14", "A15", "B16", "C16", "D17", "E15", "G15", "M15", "B17", "C17", "D18", "G16", "B18", "D19", "G17", "B19", "D20", "B20", "D21", "T1"]; // Ensure T1 is present - -// 96 Color Palette Keys (from user table) -const palette96Keys = ["A3", "A4", "A6", "A7", "A10", "A11", "A13", "A14", "B3", "B5", "B7", "B8", "B10", "B12", "B14", "B17", "B18", "B19", "B20", "C2", "C3", "C5", "C6", "C7", "C8", "C10", "C11", "C13", "C16", "D2", "D3", "D5", "D6", "D7", "D8", "D9", "D11", "D12", "D13", "D14", "D15", "D16", "D18", "D19", "D20", "D21", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "E10", "E11", "E12", "E13", "E14", "E15", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "F13", "F14", "G1", "G2", "G3", "G5", "G7", "G8", "G9", "G13", "G14", "G17", "H1", "H2", "H3", "H4", "H5", "H6", "H7", "M5", "M6", "M9", "M12", "T1"]; // Added T1 - -// 120 Color Palette Keys (from user table) -const palette120Keys = ["A1", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "A10", "A11", "A12", "A13", "A14", "A15", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B10", "B11", "B12", "B13", "B14", "B15", "B16", "B17", "B18", "B19", "B20", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "C10", "C11", "C13", "C14", "C15", "C16", "C17", "D1", "D2", "D3", "D5", "D6", "D7", "D8", "D9", "D11", "D12", "D13", "D14", "D15", "D16", "D17", "D18", "D19", "D20", "D21", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "E10", "E11", "E12", "E13", "E14", "E15", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "F13", "F14", "G1", "G2", "G3", "G5", "G6", "G7", "G8", "G9", "G13", "G14", "G17", "H1", "H2", "H3", "H4", "H5", "H6", "H7", "H12", "M5", "M6", "M9", "M12", "T1"]; // Added T1 - -// 72 Color Palette Keys (from user table) -const palette72Keys = ["A3", "A4", "A6", "A7", "A10", "A11", "A13", "B3", "B5", "B7", "B8", "B10", "B12", "B14", "B17", "B18", "B19", "B20", "C2", "C3", "C5", "C6", "C7", "C8", "C10", "C11", "C13", "C16", "D2", "D3", "D6", "D7", "D8", "D9", "D11", "D12", "D13", "D14", "D15", "D16", "D18", "D19", "D20", "D21", "E1", "E2", "E3", "E4", "E5", "E8", "E12", "E13", "F5", "F7", "F8", "F10", "F13", "G1", "G2", "G3", "G5", "G7", "G8", "G9", "G13", "H1", "H2", "H3", "H4", "H5", "H7", "T1"]; // Added T1 - -// Placeholder for other palettes -// const palette48Keys = [...]; -// const palette24Keys = [...]; - -const paletteOptions = { - 'all': { name: `全色系291色`, keys: allPaletteKeys }, - '168': { name: '168色', keys: palette168Keys }, - '144': { name: '144色', keys: palette144Keys }, - '120': { name: '120色', keys: palette120Keys }, - '96': { name: '96色', keys: palette96Keys }, - '72': { name: '72色', keys: palette72Keys }, // Added 72 - // Add other palettes here -}; - -type PaletteOptionKey = keyof typeof paletteOptions; - -// Pre-process the FULL palette data once -const fullBeadPalette: PaletteColor[] = Object.entries(beadPaletteData) - .map(([key, hex]) => { +// Pre-process the FULL palette data once - 使用colorSystemMapping而不是beadPaletteData +const fullBeadPalette: PaletteColor[] = Object.entries(mardToHexMapping) + .map(([mardKey, hex]) => { const rgb = hexToRgb(hex); if (!rgb) { - console.warn(`Invalid hex code "${hex}" for key "${key}". Skipping.`); + console.warn(`Invalid hex code "${hex}" for MARD key "${mardKey}". Skipping.`); return null; } - return { key, hex, rgb }; + // 使用hex值作为key,符合新的架构设计 + return { key: hex, hex, rgb }; }) .filter((color): color is PaletteColor => color !== null); @@ -120,7 +90,7 @@ const transparentColorData: MappedPixel = { key: TRANSPARENT_KEY, color: '#FFFFF import PixelatedPreviewCanvas from '../components/PixelatedPreviewCanvas'; import GridTooltip from '../components/GridTooltip'; import CustomPaletteEditor from '../components/CustomPaletteEditor'; -import { loadPaletteSelections, savePaletteSelections, presetToSelections, presetKeysToHexSelections, PaletteSelections } from '../utils/localStorageUtils'; +import { loadPaletteSelections, savePaletteSelections, presetToSelections, PaletteSelections } from '../utils/localStorageUtils'; // 1. 导入新的 DonationModal 组件 import DonationModal from '../components/DonationModal'; @@ -133,17 +103,12 @@ export default function Home() { const [similarityThresholdInput, setSimilarityThresholdInput] = useState("30"); // 添加像素化模式状态 const [pixelationMode, setPixelationMode] = useState(PixelationMode.Dominant); // 默认为卡通模式 - const [selectedPaletteKeySet, setSelectedPaletteKeySet] = useState('all'); // 新增:色号系统选择状态 const [selectedColorSystem, setSelectedColorSystem] = useState('MARD'); const [activeBeadPalette, setActiveBeadPalette] = useState(() => { - const initialKey = 'all'; // Match the key used above - const options = paletteOptions[initialKey]; - if (!options) return fullBeadPalette; // Fallback - const keySet = new Set(options.keys); - return fullBeadPalette.filter(color => keySet.has(color.key)); + return fullBeadPalette; // 默认使用全部颜色 }); // 状态变量:存储被排除的颜色(hex值) const [excludedColorKeys, setExcludedColorKeys] = useState>(new Set()); @@ -194,14 +159,15 @@ export default function Home() { // Update active palette based on selection and exclusions useEffect(() => { const newActiveBeadPalette = fullBeadPalette.filter(color => { - const isInSelectedPalette = paletteOptions[selectedPaletteKeySet]?.keys.includes(color.key); - const isNotExcluded = !excludedColorKeys.has(color.key); - return isInSelectedPalette && isNotExcluded; + const normalizedHex = color.hex.toUpperCase(); + const isSelectedInCustomPalette = customPaletteSelections[normalizedHex]; + const isNotExcluded = !excludedColorKeys.has(normalizedHex); + return isSelectedInCustomPalette && isNotExcluded; }); // 根据选择的色号系统转换调色板 const convertedPalette = convertPaletteToColorSystem(newActiveBeadPalette, selectedColorSystem); setActiveBeadPalette(convertedPalette); - }, [selectedPaletteKeySet, excludedColorKeys, remapTrigger, selectedColorSystem]); + }, [customPaletteSelections, excludedColorKeys, remapTrigger, selectedColorSystem]); // ++ 添加:当状态变化时同步更新输入框的值 ++ useEffect(() => { @@ -277,22 +243,22 @@ export default function Home() { setIsCustomPalette(true); } else { console.log('所有数据都无效,清除localStorage并重新初始化'); - // 如果本地数据无效,清除localStorage并用当前预设初始化 + // 如果本地数据无效,清除localStorage并默认选择所有颜色 localStorage.removeItem('customPerlerPaletteSelections'); - const currentPresetKeys = paletteOptions[selectedPaletteKeySet]?.keys || []; - const initialSelections = presetKeysToHexSelections(fullBeadPalette, currentPresetKeys); + const allHexValues = fullBeadPalette.map(color => color.hex.toUpperCase()); + const initialSelections = presetToSelections(allHexValues, allHexValues); setCustomPaletteSelections(initialSelections); setIsCustomPalette(false); } } else { - console.log('没有localStorage数据,使用预设初始化'); - // 如果没有保存的选择,用当前预设初始化 - const currentPresetKeys = paletteOptions[selectedPaletteKeySet]?.keys || []; - const initialSelections = presetKeysToHexSelections(fullBeadPalette, currentPresetKeys); + console.log('没有localStorage数据,默认选择所有颜色'); + // 如果没有保存的选择,默认选择所有颜色 + const allHexValues = fullBeadPalette.map(color => color.hex.toUpperCase()); + const initialSelections = presetToSelections(allHexValues, allHexValues); setCustomPaletteSelections(initialSelections); setIsCustomPalette(false); } - }, [selectedPaletteKeySet]); + }, []); // 只在组件首次加载时执行 // 更新 activeBeadPalette 基于自定义选择和排除列表 useEffect(() => { @@ -703,7 +669,6 @@ export default function Home() { totalBeadCount, options: options || downloadOptions, activeBeadPalette, - selectedPaletteKeySet, selectedColorSystem }); }; @@ -1097,24 +1062,6 @@ export default function Home() { setIsCustomPalette(true); }; - // 应用预设到自定义色板 - const handleApplyPreset = (presetKey: string) => { - // 检查是否为有效的预设键 - if (!Object.keys(paletteOptions).includes(presetKey)) { - console.warn(`无效的预设键: ${presetKey}`); - return; - } - - const typedPresetKey = presetKey as PaletteOptionKey; - const presetKeys = paletteOptions[typedPresetKey].keys || []; - const newSelections = presetKeysToHexSelections(fullBeadPalette, presetKeys); - setCustomPaletteSelections(newSelections); - setSelectedPaletteKeySet(typedPresetKey); // 同步更新预设选择状态 - setIsCustomPalette(false); // 应用预设后,标记为非自定义(除非用户再次修改) - // 不要在这里关闭编辑器,让用户可以继续编辑 - // setIsCustomPaletteEditorOpen(false); - }; - // 保存自定义色板并应用 const handleSaveCustomPalette = () => { savePaletteSelections(customPaletteSelections); @@ -1517,11 +1464,8 @@ export default function Home() { allColors={fullBeadPalette} currentSelections={customPaletteSelections} onSelectionChange={handleSelectionChange} - onApplyPreset={handleApplyPreset} onSaveCustomPalette={handleSaveCustomPalette} onClose={() => setIsCustomPaletteEditorOpen(false)} - paletteOptions={paletteOptions} - // ++ 传递新的处理函数 ++ onExportCustomPalette={handleExportCustomPalette} onImportCustomPalette={triggerImportPalette} selectedColorSystem={selectedColorSystem} @@ -1550,7 +1494,7 @@ export default function Home() { className={`w-full py-2.5 px-4 text-sm sm:text-base rounded-lg transition-all duration-200 flex items-center justify-center gap-2 bg-red-500 hover:bg-red-600 text-white shadow-sm hover:shadow-md`} // Keep red for contrast? > - 完成手动上色 + 完成手动编辑 {/* Color Palette (only in manual mode) */}
@@ -1787,7 +1731,7 @@ export default function Home() { className={`w-full py-2.5 px-4 text-sm sm:text-base rounded-lg transition-all duration-300 flex items-center justify-center gap-2 bg-gradient-to-r from-blue-500 to-blue-600 hover:from-blue-600 hover:to-blue-700 text-white shadow-md hover:shadow-lg hover:translate-y-[-1px]`} > - 进入手动上色模式 + 进入手动编辑模式(含去背景)
)} {/* ++ End of RENDER Enter Manual Mode Button ++ */} diff --git a/src/components/CustomPaletteEditor.tsx b/src/components/CustomPaletteEditor.tsx index ddfb85d..12365ea 100644 --- a/src/components/CustomPaletteEditor.tsx +++ b/src/components/CustomPaletteEditor.tsx @@ -69,10 +69,8 @@ interface CustomPaletteEditorProps { allColors: PaletteColor[]; currentSelections: PaletteSelections; onSelectionChange: (key: string, isSelected: boolean) => void; - onApplyPreset: (presetKey: string) => void; onSaveCustomPalette: () => void; onClose: () => void; - paletteOptions: Record; onExportCustomPalette: () => void; onImportCustomPalette: () => void; selectedColorSystem: ColorSystem; @@ -82,10 +80,8 @@ const CustomPaletteEditor: React.FC = ({ allColors, currentSelections, onSelectionChange, - onApplyPreset, onSaveCustomPalette, onClose, - paletteOptions, onExportCustomPalette, onImportCustomPalette, selectedColorSystem, @@ -156,41 +152,22 @@ const CustomPaletteEditor: React.FC = ({ - {/* 搜索和预设 */} -
-
-
- setSearchTerm(e.target.value)} - className="w-full px-3 py-2 pl-9 border border-gray-300 dark:border-gray-600 rounded-md text-sm bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-200 focus:ring-blue-500 focus:border-blue-500" - /> -
- - - -
+ {/* 搜索框 */} +
+
+ setSearchTerm(e.target.value)} + className="w-full px-3 py-2 pl-9 border border-gray-300 dark:border-gray-600 rounded-md text-sm bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-200 focus:ring-blue-500 focus:border-blue-500" + /> +
+ + +
- -
- -
{/* 说明文本 */} diff --git a/src/utils/colorSystemUtils.ts b/src/utils/colorSystemUtils.ts index a9f7beb..6c02098 100644 --- a/src/utils/colorSystemUtils.ts +++ b/src/utils/colorSystemUtils.ts @@ -1,6 +1,5 @@ import { PaletteColor } from './pixelation'; import colorSystemMapping from '../app/colorSystemMapping.json'; -import beadPaletteData from '../app/beadPaletteData.json'; // 定义色号系统类型并导出 export type ColorSystem = 'MARD' | 'COCO' | '漫漫' | '盼盼' | '咪小窝'; @@ -17,7 +16,23 @@ export const colorSystemOptions = [ // 类型定义 type ColorMapping = Record>; const typedColorSystemMapping = colorSystemMapping as ColorMapping; -const typedBeadPaletteData = beadPaletteData as Record; + +// 获取所有可用的hex值 +export function getAllHexValues(): string[] { + return Object.keys(typedColorSystemMapping); +} + +// 获取所有MARD色号到hex值的映射(用于向后兼容) +export function getMardToHexMapping(): Record { + const mapping: Record = {}; + Object.entries(typedColorSystemMapping).forEach(([hex, colorData]) => { + const mardKey = colorData.MARD; + if (mardKey) { + mapping[mardKey] = hex; + } + }); + return mapping; +} // 从colorSystemMapping.json加载完整的颜色映射数据 export function loadFullColorMapping(): Map> { @@ -45,44 +60,39 @@ export function convertPaletteToColorSystem( }); } -// 获取指定色号系统的显示键 - 重新设计的简化版本 -export function getDisplayColorKey(originalKey: string, colorSystem: ColorSystem): string { +// 获取指定色号系统的显示键 - 基于hex值的简化版本 +export function getDisplayColorKey(hexValue: string, colorSystem: ColorSystem): string { // 对于特殊键(如透明键),直接返回原键 - if (originalKey === 'ERASE' || originalKey.length === 0 || originalKey === '?') { - return originalKey; + if (hexValue === 'ERASE' || hexValue.length === 0 || hexValue === '?') { + return hexValue; } - // 如果目标色号系统就是MARD,直接返回原键 - if (colorSystem === 'MARD') { - return originalKey; - } + // 标准化hex值(确保大写) + const normalizedHex = hexValue.toUpperCase(); - // 1. 通过MARD色号从beadPaletteData获取hex值 - const hexValue = typedBeadPaletteData[originalKey]; - if (!hexValue) { - return originalKey; // 如果找不到对应的hex值,返回原键 - } - - // 2. 通过hex值从colorSystemMapping获取目标色号系统的值 - const colorMapping = typedColorSystemMapping[hexValue]; + // 通过hex值从colorSystemMapping获取目标色号系统的值 + const colorMapping = typedColorSystemMapping[normalizedHex]; if (colorMapping && colorMapping[colorSystem]) { return colorMapping[colorSystem]; } - return originalKey; // 如果找不到映射,返回原键 + return '?'; // 如果找不到映射,返回 '?' } -// 将色号键转换回基础系统(MARD) -export function convertToBaseKey(displayKey: string, colorSystem: ColorSystem): string { - if (colorSystem === 'MARD') { - return displayKey; +// 将色号键转换到hex值(支持任意色号系统) +export function convertColorKeyToHex(displayKey: string, colorSystem: ColorSystem): string { + // 如果已经是hex值,直接返回 + if (displayKey.startsWith('#') && displayKey.length === 7) { + return displayKey.toUpperCase(); } - for (const [, mapping] of Object.entries(typedColorSystemMapping)) { + // 在colorSystemMapping中查找对应的hex值 + for (const [hex, mapping] of Object.entries(typedColorSystemMapping)) { if (mapping[colorSystem] === displayKey) { - return mapping.MARD; + return hex; } } + return displayKey; // 如果找不到映射,返回原键 } @@ -103,6 +113,6 @@ export function getColorKeyByHex(hexValue: string, colorSystem: ColorSystem): st return mapping[colorSystem]; } - // 如果找不到映射,返回 hex 值本身或者 '?' + // 如果找不到映射,返回 '?' return '?'; } \ No newline at end of file diff --git a/src/utils/imageDownloader.ts b/src/utils/imageDownloader.ts index 16ba2a4..1b8d072 100644 --- a/src/utils/imageDownloader.ts +++ b/src/utils/imageDownloader.ts @@ -47,14 +47,13 @@ function sortColorKeys(a: string, b: string): number { } // 下载图片的主函数 -export function downloadImage({ +export async function downloadImage({ mappedPixelData, gridDimensions, colorCounts, totalBeadCount, options, activeBeadPalette, - selectedPaletteKeySet, selectedColorSystem }: { mappedPixelData: MappedPixel[][] | null; @@ -63,9 +62,8 @@ export function downloadImage({ totalBeadCount: number; options: GridDownloadOptions; activeBeadPalette: PaletteColor[]; - selectedPaletteKeySet: string; selectedColorSystem: ColorSystem; -}): void { +}): Promise { if (!mappedPixelData || !gridDimensions || gridDimensions.N === 0 || gridDimensions.M === 0 || activeBeadPalette.length === 0) { console.error("下载失败: 映射数据或尺寸无效。"); alert("无法下载图纸,数据未生成或无效。"); @@ -523,7 +521,7 @@ export function downloadImage({ try { const dataURL = downloadCanvas.toDataURL('image/png'); const link = document.createElement('a'); - link.download = `bead-grid-${N}x${M}-keys-palette_${selectedPaletteKeySet}.png`; // 文件名包含调色板 + link.download = `bead-grid-${N}x${M}-keys-palette_${selectedColorSystem}.png`; // 文件名包含色彩系统 link.href = dataURL; document.body.appendChild(link); link.click();