首页 > 解决方案 > 在 javascript / p5.js 中查找与当前颜色最接近的索引颜色值

问题描述

我有一个“索引”RGBA 颜色值数组,对于我加载的任何给定图像,我希望能够遍历加载像素的所有颜色值,并将它们与最接近的索引颜色值匹配。因此,如果图像中的像素具有 RGBA(0,0,10,1) 的颜色,并且颜色 RGBA(0,0,0,1) 是我最接近的索引值,它将调整加载的像素到 RGBA(0,0,0,1)。

我知道 PHP 有一个函数imagecolorclosest

int imagecolorclosest( $image, $red, $green, $blue )

javascript / p5.js / processing 有类似的吗?将一种颜色与另一种颜色进行比较的最简单方法是什么。目前我可以使用此代码(使用 P5.js)读取图像的像素:

let img;
function preload() {
  img = loadImage('assets/00.jpg');
}

function setup() {
  image(img, 0, 0, width, height);
  let d = pixelDensity();
  let fullImage = 4 * (width * d) * (height * d);
  loadPixels();
  for (let i = 0; i < fullImage; i+=4) {
    let curR = pixels[i];
    let curG = pixels[i]+1;
    let curB = pixels[i+2];
    let curA = pixels[i+3];
  }
  updatePixels();
}

标签: javascriptprocessingp5.js

解决方案


如果我对您的理解正确,您希望将图像的颜色保持在某个有限的托盘内。如果是这样,您应该将此函数应用于图像的每个像素。它将为您提供一组有限颜色 (indexedColors) 中与所提供像素最接近的颜色值。

// example color pallet (no alpha)
indexedColors = [
  [0, 10, 0],
  [0, 50, 0]
];

// Takes pixel with no alpha value
function closestIndexedColor(color) {
  var closest = {};
  var dist;
  for (var i = 0; i < indexedColors.length; i++) {
    dist = Math.pow(indexedColors[i][0] - color[0], 2);
    dist += Math.pow(indexedColors[i][1] - color[1], 2);
    dist += Math.pow(indexedColors[i][2] - color[2], 2);
    dist = Math.sqrt(dist);

    if(!closest.dist || closest.dist > dist){
        closest.dist = dist;
      closest.color = indexedColors[i];
    }
  }
  // returns closest match as RGB array without alpha
  return closest.color;
}

// example usage
closestIndexedColor([0, 20, 0]); // returns [0, 10, 0]

它的工作方式与您提到的 PHP 函数一样。如果您将颜色值视为 3d 坐标点,那么最接近的颜色将是它们之间 3d“距离”最小的颜色。这个 3d 距离是使用距离公式计算的:

3d 距离公式


推荐阅读