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

使用JavaScript实现指定8色图片量化 解决输出仅为灰度的问题

问题原因

你当前代码的问题在于完全没有用到预设的8色彩色调色板的颜色值:仅对像素的亮度值做了分级量化,然后把相同的量化后亮度值赋值给R/G/B三个通道,最终得到的必然是灰度图片。

修复方案

核心逻辑需要调整为:对每个原始像素的RGB值,逐一计算和调色板中每个颜色的距离,找到距离最小的对应调色板颜色,再把该颜色的三个通道值分别赋值给目标像素的R/G/B通道即可得到彩色量化结果。

修正后可直接运行的代码
// 把调色板定义放到循环外,避免重复创建浪费性能
const palette = [ [240, 242,254], [179, 168, 164], [121,192, 246], [103,185,183], [255,201,157], [215,134,94], [67,38,158], [165,104,57]];

for(let x = 0; x < image.width; x++){
    for(let y = 0; y < image.height; y++){
        const i = y * image.width + x;
        const i_r = i*4+0;
        const i_g = i*4+1;
        const i_b = i*4+2;
        const r = rgba[i_r];
        const g = rgba[i_g];
        const b = rgba[i_b];

        let minDistance = Infinity;
        let bestColor = palette[0];
        // 遍历所有调色板颜色,找到距离最小的匹配项
        for (const color of palette) {
            const [pr, pg, pb] = color;
            // 采用加权RGB距离,更符合人眼对颜色的感知,也可以替换为普通欧氏距离 `(r-pr)**2 + (g-pg)**2 + (b-pb)**2`
            const distance = 2 * (r - pr)**2 + 4 * (g - pg)**2 + 3 * (b - pb)**2;
            if (distance < minDistance) {
                minDistance = distance;
                bestColor = color;
            }
        }

        // 替换为匹配到的彩色调色板颜色
        rgba[i_r] = bestColor[0];
        rgba[i_g] = bestColor[1];
        rgba[i_b] = bestColor[2];
    }
}
可选优化点
  • 若需要更高的颜色匹配精度,可以提前把调色板和原始像素颜色转换为LAB颜色空间再计算距离
  • 若需要避免大面积色块出现明显色带,可以叠加弗洛伊德-斯坦伯格抖动算法处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 16:36:08