javascript - HTML5 Canvas,替换图像中的颜色在某些机器上不起作用

标签 javascript html canvas

我有一个 2d RTS HTML5/Javascript 游戏。我使用图像来显示玩家的单位和建筑物。我提供图像,然后使用脚本将图像中的某些颜色替换为其他颜色,以获得具有不同颜色的图像的不同版本(因此玩家 1 的士兵有一把红色剑,而玩家 2 的士兵有一把蓝色剑)剑等等...)。 问题是,对于大约 20% 的用户来说,这种替换方法不起作用,他们看到所有单位都是相同的(默认)颜色。我现在想知道这是为什么。这是我用来重放颜色的函数:

// returns a image with some colors replaced, specified by search and replace, which are arrays of color arrays ([[255, 255, 255], [...], ...], )
ImageTransformer.replaceColors = function(img, search, replace)
{
    var canv = document.createElement('canvas');
    canv.height = img.height;
    canv.width = img.width
    var ctx = canv.getContext('2d');

    ctx.drawImage(img, 0, 0);

    var imgData = ctx.getImageData(0, 0, canv.width, canv.height);

    for(var i = 0; i < imgData.data.length; i += 4)
        for(var k = 0; k < search.length; k++)
            if(imgData.data[i] == search[k][0] && imgData.data[i + 1] == search[k][1] && imgData.data[i + 2] == search[k][2])
            {
                imgData.data[i] = replace[k][0];
                imgData.data[i + 1] = replace[k][1];
                imgData.data[i + 2] = replace[k][2];
            }

    ctx.putImageData(imgData, 0, 0);

    return canv;
}

最佳答案

浏览器在绘制图像之前可能会也可能不会对图像应用 Gamma ,目的是获得更自然的颜色 (...)。
我敢打赌,这是应用 Gamma 的浏览器欺骗了你的算法。

您可以使用颜色距离,并确定阈值来决定是否切换,而不是测试严格相等:

var imgData = ctx.getImageData(0, 0, canv.width, canv.height);
var data = imgData.data, length = imgData.data.length ;

    for(var k = 0; k < search.length; k++) {
       var thisCol = search[k];
       for(var i = 0; i < length; i += 4) {
            var colDist = Math.abs(data[i] - thisCol[0] ) 
                          + Math.abs(data[i+1] - thisCol[1] ) 
                            + Math.abs(data[i+2] - thisCol[2] );
            if( colDist < 5 )
           {
              data[i] = thisCol[0];
              data[i + 1] = thisCol[1];
              data[i + 2] = thisCol[2];
           }
     }
}

ctx.putImageData(imgData, 0, 0);

return canv; 
<小时/>

(这里我使用 r,g,b 之间的绝对差之和作为距离;正如@MarkE建议的那样,你可以选择其他的,欧几里得是这样的:

        var colDist = sq(data[i] - thisCol[0] ) 
                      + sq(data[i+1] - thisCol[1] ) 
                        + sq(data[i+2] - thisCol[2] );
       // notice this is the squared euclidian distance.
       // whith function sq(x) { return x*x }

测试几张图片/距离,看看哪个合适。

还测试几个阈值。
)。

关于javascript - HTML5 Canvas,替换图像中的颜色在某些机器上不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24268329/

相关文章:

javascript - 清除 setTimeout 的数组

javascript - Flowtype:与具有可选属性的对象的子类型关系

javascript - Kendo UI line Graph,如何防止标签被绘制到图表之外?

jquery - 使用 jQuery 删除选定的项目

java - 使用 $ ('html' ).html(data); Bootstrap 未 100%

javascript - 在 Canvas 上挥动文字

javascript - 无法注入(inject)自定义存储库

html - 如何设置 mat-toolbar-row 使其颜色为 "primary"?

javascript - 如何使用非递归算法填充区域?

javascript - 图像过滤器在 Fabric.js 中的克隆对象之间共享