You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于SVG彩色与轮廓图开发Illustrator数字填色脚本需求

解决方案:SVG彩色图转数字填色工作表

核心思路

基于SVG的DOM结构,提取彩色图的填充色数据,通过色彩聚类合并相近色调,建立色彩与编号的映射,再将编号标注到轮廓图对应区域,最后生成带编号调色板的完整填色工作表。

具体实现步骤

1. 色彩分组融合

  • 提取彩色SVG中所有非透明、非渐变的填充色,统一转换为RGB格式便于计算
  • 使用K-means聚类算法对色彩分组,可根据人工编辑需求设置聚类数量(建议20-30组,平衡细节与工作量)
  • 聚类时优先保留画面主色调,自动合并HSL空间差值较小的相近色调,每组取中心色作为调色板基准色

2. 调色板生成与色彩映射

  • 将聚类后的中心色按顺序编号,在轮廓图底部生成横向排列的调色板,每个色块下方标注对应数字(可设置色块大小、间距统一样式)
  • 建立「原色彩→聚类组编号」的映射表,确保同一聚类组内的所有原色彩对应同一个编号

3. 轮廓图区域数字标注

  • 提前确保彩色图与轮廓图的区域ID一一对应(若未对应,可通过路径形状相似度、轮廓矩计算匹配)
  • 遍历轮廓图的每个区域,根据对应彩色区域的原色彩查找映射编号,在区域中心位置添加文本标注(字号根据区域大小自动适配,避免溢出)

4. 原有脚本的适配修改

  • 补充色彩聚类模块:引入chroma.js简化色彩计算,替换原脚本中直接匹配色彩的逻辑
  • 添加区域匹配逻辑:通过ID直接关联或路径特征计算,实现彩色图与轮廓图区域的对应
  • 新增调色板生成函数:自动在SVG底部插入色块和文本元素,完成布局

核心代码示例

// 提取彩色SVG中的填充色(排除渐变、透明)
function extractFillColors(svgDoc) {
  const colorList = [];
  const fillElements = svgDoc.querySelectorAll('[fill]:not([fill="none"]):not([fill^="url("])');
  
  fillElements.forEach(el => {
    const hexColor = chroma(el.getAttribute('fill')).hex();
    colorList.push(hexColor);
  });
  return [...new Set(colorList)]; // 去重
}

// K-means色彩聚类,生成调色板与映射表
function buildColorMap(rawColors, clusterCount) {
  // 将原始颜色聚类为指定数量的调色板色
  const palette = chroma.scale(rawColors).mode('lch').colors(clusterCount);
  const colorToNumber = new Map();

  rawColors.forEach(color => {
    // 找到当前颜色最接近的调色板色
    const closestPaletteColor = palette.reduce((prev, curr) => 
      chroma.distance(color, curr) < chroma.distance(color, prev) ? curr : prev
    );
    // 编号从1开始(符合填色习惯)
    colorToNumber.set(color, palette.indexOf(closestPaletteColor) + 1);
  });

  return { palette, colorToNumber };
}

// 为轮廓图区域添加数字标注
function addNumberLabels(outlineSvg, colorMap, regionIdToColor) {
  const paths = outlineSvg.querySelectorAll('path');
  
  paths.forEach(path => {
    const regionId = path.getAttribute('id');
    const targetColor = regionIdToColor.get(regionId);
    
    if (targetColor && colorMap.has(targetColor)) {
      const number = colorMap.get(targetColor);
      const bbox = path.getBBox();
      
      // 创建SVG文本元素
      const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
      text.setAttribute('x', bbox.x + bbox.width / 2);
      text.setAttribute('y', bbox.y + bbox.height / 2);
      text.setAttribute('text-anchor', 'middle');
      text.setAttribute('dominant-baseline', 'middle');
      text.setAttribute('font-size', Math.max(8, Math.min(bbox.width, bbox.height) / 6));
      text.textContent = number;
      
      path.parentNode.appendChild(text);
    }
  });
}

// 生成底部调色板
function generatePalette(svgDoc, palette, colorToNumber) {
  const svgWidth = parseFloat(svgDoc.getAttribute('width'));
  const paletteHeight = 40;
  const blockWidth = svgWidth / palette.length;
  
  // 调整SVG高度,留出调色板空间
  svgDoc.setAttribute('height', parseFloat(svgDoc.getAttribute('height')) + paletteHeight + 10);
  
  palette.forEach((color, index) => {
    const number = index + 1;
    // 创建色块
    const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
    rect.setAttribute('x', index * blockWidth);
    rect.setAttribute('y', parseFloat(svgDoc.getAttribute('height')) - paletteHeight);
    rect.setAttribute('width', blockWidth);
    rect.setAttribute('height', paletteHeight - 10);
    rect.setAttribute('fill', color);
    rect.setAttribute('stroke', '#000');
    
    // 创建数字标签
    const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
    text.setAttribute('x', index * blockWidth + blockWidth / 2);
    text.setAttribute('y', parseFloat(svgDoc.getAttribute('height')) - 5);
    text.setAttribute('text-anchor', 'middle');
    text.setAttribute('font-size', 12);
    text.textContent = number;
    
    svgDoc.appendChild(rect);
    svgDoc.appendChild(text);
  });
}

内容的提问来源于stack exchange,提问作者Ivan Octavian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 16:20:22