【问题标题】:Converting images into a linear color palette with JS, losing colors用JS把图片转成线性调色板,掉色
【发布时间】:2014-02-08 09:37:13
【问题描述】:

有问题的项目:https://github.com/matutter/Pixel2 是一个个人项目,用于替换工作中的一些过时软件。它应该做的是,用户添加图像并生成图像的调色板。调色板不应有重复的颜色。 (这是唯一重要的东西)

我的问题是:为什么较大、高分辨率或复杂的图像不能正常工作? (颜色数据丢失)

使用 dropzone.js,我让用户在页面上放了一张图片。图片是缩略图。接下来我使用 jquery 从<img src="..."> 中查找 src。我将该 src 传递给执行此操作的函数

function generate(imgdata) {
  var imageObj = new Image();
  imageObj.src = imgdata;
  convert(imageObj); //the function that traverses the image data pulling out RGB
}

“转换”功能相当简单地通过

for(var i=0, n=data.length; i<n; i+=4, pixel++ ) {
    r = data[i];
    g = data[i+1];
    b = data[i+2];
    color = r + g + b; // format is a string of **r, g, b**
}

最后,主要算法的最后一部分过滤掉重复的颜色,我只想要每个出现 1 次...这是最后一部分

color   = monoFilter(color); // the call

function monoFilter(s) {
    var unique = [];
    $.each(s, function(i, el){
        if($.inArray(el, unique) === -1) unique.push(el);
    });
    unique.splice(0,1); //remove undefine
    unique.unshift("0, 0, 0");    //make sure i have black
    unique.push("255, 255, 255"); //and white
    return unique;
}

我希望有人能帮我找出大文件中颜色数据丢失的原因。

如果有人真的很有趣可以看看 github,relivent 文件是 js/pixel2.js、js/dropzone.js 和 ../index.html

【问题讨论】:

  • 也许我理解错了,但为什么不在第一遍将颜色存储在关联数组中呢? allColors[r + g + b]=1
  • 问题是如果图像很大,为什么这个过程不能找到所有颜色。然而,这不是一个坏主意,几乎可以跳过删除重复项的需要。
  • 它应该完全跳过删除重复项的需要,因为这将由存储的性质完成。
  • 是的,完全!但我也使用该数组不仅生成调色板,我还将使用包含所有像素和颜色信息的未排序版本的数组来生成特殊的类似二进制的图像格式。
  • 你也可以从关联数组构建一个真正的数组。

标签: node.js html5-canvas dropzone.js color-palette


【解决方案1】:

“问题是我没有考虑 alpha。所以使用 alpha 的图像中的调色板会意外地出现重复记录。”

我在找到这个Convert RGBA color to RGB后想通了

【讨论】:

    【解决方案2】:

    这可能是问题的原因:

    color = r + g + b; // format is a string of **r, g, b**
    

    这只是将数字相加,像素越多,获得相同数字的风险就越高。例如,这些颜色会产生相同的结果:

            R    G   B
    color = 90 + 0 + 0 = 90;
    color = 0 + 90 + 0 = 90;
    color = 0 + 0 + 90 = 90;
    

    即使它们是完全不同的颜色。

    为了避免这种情况,如果你想要一个字符串,你可以这样做:

    color = [r,g,b].join();
    

    或者您可以为它们创建一个整数值(与字符串相比更快):

    color = (b << 16) + (g << 8) + r;   /// LSB byte-order
    

    即使是欧几里得向量也会更好:

    color = r*r + g*g + b*b;
    

    但对于后者,您最终会面临与最初场景相同的风险(但对最近的颜色场景很有用)。

    无论如何,希望这会有所帮助。

    【讨论】:

    • 它们被正确地作为字符串处理。我的问题是,如果我有一张具有 30000 种独特颜色的图像,我可能只能捕获 300 种。
    猜你喜欢
    • 2011-11-06
    • 1970-01-01
    • 2014-12-15
    • 2019-01-16
    • 1970-01-01
    • 1970-01-01
    • 2013-01-12
    • 2019-02-08
    • 1970-01-01
    相关资源
    最近更新 更多