从画布像素数据获取错误的RGB值

7

我正在画布上绘制4个矩形,每个矩形都有不同的颜色:

enter image description here

Rectangle 1: rgb(38, 94, 33)
Rectangle 2: rgb(96, 231, 42)
Rectangle 3: rgb(190, 152, 213)
Rectangle 4: rgb(57, 93, 254)

现在,如果我使用ctx.getImageData()获取绘制这些矩形的像素的RGB值。RGB值与我设置的值不对应。
let imgData1 = ctx.getImageData(50, 50, 1, 1).data;
let imgData2 = ctx.getImageData(150, 50, 1, 1).data;
let imgData3 = ctx.getImageData(250, 50, 1, 1).data;
let imgData4 = ctx.getImageData(350, 50, 1, 1).data;

rgb(39, 94, 32)     --> should be rgb(38, 94, 33)
rgb(97, 231, 43)    --> should be rgb(96, 231, 42)
rgb(191, 152, 212)  --> should be rgb(190, 152, 213)
rgb(56, 92, 254)    --> should be rgb(57, 93, 254)

有任何想法吗?


更新:

显然这是一个浏览器问题。我使用的是Brave浏览器(版本1.23.75 Chromium: 90.0.4430.93 (官方版本) (x86_64))。在Chrome、Firefox和Safari中似乎正常工作。


let width = 400;
let height = 300;

let canvas = document.getElementById('canvas');
canvas.width = width;
canvas.height = height;

let ctx = canvas.getContext('2d');

let c1 = 'rgb(38, 94, 33)';
let c2 = 'rgb(96, 231, 42)';
let c3 = 'rgb(190, 152, 213)';
let c4 = 'rgb(57, 93, 254)';

ctx.beginPath();
ctx.rect(50,50,50,50);
ctx.fillStyle  = c1;
ctx.fill();

ctx.beginPath();
ctx.rect(150,50,50,50);
ctx.fillStyle  = c2;
ctx.fill();

ctx.beginPath();
ctx.rect(250,50,50,50);
ctx.fillStyle  = c3;
ctx.fill();

ctx.beginPath();
ctx.rect(350,50,50,50);
ctx.fillStyle  = c4;
ctx.fill();

let imgData1 = ctx.getImageData(50, 50, 1, 1).data;
let imgData2 = ctx.getImageData(150, 50, 1, 1).data;
let imgData3 = ctx.getImageData(250, 50, 1, 1).data;
let imgData4 = ctx.getImageData(350, 50, 1, 1).data;

console.log(`rgb(${imgData1[0]}, ${imgData1[1]}, ${imgData1[2]}) --> Should be ${c1}`);
console.log(`rgb(${imgData2[0]}, ${imgData2[1]}, ${imgData2[2]}) --> Should be ${c2}`);
console.log(`rgb(${imgData3[0]}, ${imgData3[1]}, ${imgData3[2]}) --> Should be ${c3}`);
console.log(`rgb(${imgData4[0]}, ${imgData4[1]}, ${imgData4[2]}) --> Should be ${c4}`);
<canvas id="canvas"></canvas>


1
当我在Firefox中运行StackSnippet时,值是相等的。对于Chrome和Edge也是如此。您正在测试哪个浏览器? - Teemu
哎呀,不会吧!我正在使用Brave浏览器。刚在Chrome和Safari上测试了一下,似乎也能正常工作。哈哈。 - Ivan Bacher
也许他们通过降低颜色来使Brave浏览器更快了..? - Teemu
6
勇敢浏览器非常注重隐私保护,所以我想这可能是他们对抗画布指纹识别的措施之一吧? - CBroe
1
@IvanBacher,您尝试关闭该网站的指纹保护了吗? - Ken Herbert
是的,你是正确的。看起来这是一种反指纹识别的措施。如果你关闭它,就会返回正确的值。 - Ivan Bacher
1个回答

4

你被Brave farbling 了

(答案由 @CBroe 和 @KenHerbert 提供)

Brave对“半识别的浏览器特征输出”应用一些小的、可重复的随机化操作,以防止指纹识别。他们称之为farbling

此链接中提到的可观察行为包括:

  • 在同一会话内,一个网站每次尝试进行指纹识别时都会得到完全相同的值
  • 不同的网站将得到不同的值
  • 同一网站在下一次会话中将得到不同的值

Farbling应用于以下画布功能:

  • getImageData
  • measureText
  • isPointInPath
  • isPointInStroke
  • toDataURL
  • toBlob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接