覆盖CanvasRenderingContext2D.getImageData() [英] Overriding CanvasRenderingContext2D.getImageData()

查看:289
本文介绍了覆盖CanvasRenderingContext2D.getImageData()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图重写内置方法CanvasRenderingContext2D.getImageData()。我想重写实现,以便修改的函数使用canvas上下文来修改画布,然后调用原始函数,该函数应该返回不同的数据,如果该函数未被覆盖。我这样做的原因是为了防止浏览器指纹。



canvas.js

 (function(){
'use strict';

var originalGetImageData = CanvasRenderingContext2D.prototype.getImageData;

//这个函数只加1到数组中的每个RGBA组件进行测试
//将为实际添加随机值
函数randomiseImageData(image){
var imageData = image.data;

var imageLength = imageData.length;

for(var i = 0; i< imageLength; i ++){
imageData [i] + = 1;
}
$ b $ var modifiedImage = new ImageData(image.width,image.height);
$ b $ return modifiedImage;
}

CanvasRenderingContext2D。 prototype.getImageData = function(sx,sy,sw,sh){
console.log([ALERT]+ window.location.hostname +调用CanvasRenderingContext2D.getImageData() );

const origin = window.location.hostname;

Math.seedrandom(origin);

var image = originalGetImageData.call(this,sx,sy,sw,sh);

return randomiseImageData(image);
};
})();


解决方案

strong> ImageData对象。

我猜你想要返回填充的内容。

由于您已经修改了数据数组,您可以简单地返回原始的ImageData,您的修改就已经完成了。

 



如果你真的想创建一个新的ImageData ,那么它是

 新ImageData(imageData,image.width,image.height); 
// ^^
//传递数据以填充新的ImageData对象



<但请注意,浏览器的支持并不好,而且你也不会因为这样做而赢得任何东西。


I am trying to override the built in method CanvasRenderingContext2D.getImageData(). I would like to override the implementation so that the modified function uses the canvas context to modify the canvas and then calls the original function which should return different data that if the function was not overridden. The reason I am doing this is to prevent browser fingerprinting.

canvas.js

(function(){
    'use strict';

    var originalGetImageData = CanvasRenderingContext2D.prototype.getImageData;

    // This function just adds 1 to each RGBA component in the array for testing.
    // Will add random values for the real thing.
    function randomiseImageData(image) {        
        var imageData = image.data;

        var imageLength = imageData.length;

        for (var i = 0; i < imageLength; i++) {
            imageData[i] += 1;
        }

        var modifiedImage = new ImageData(image.width, image.height);

        return modifiedImage;
    }

    CanvasRenderingContext2D.prototype.getImageData = function(sx, sy, sw, sh) {
        console.log("[ALERT] " + window.location.hostname + " called CanvasRenderingContext2D.getImageData()");

        const origin = window.location.hostname;

        Math.seedrandom(origin);

        var image = originalGetImageData.call(this, sx, sy, sw, sh);

        return randomiseImageData(image);
    };
})();

解决方案

You are returning a new empty ImageData object.

I guess what you want is to return the filled one.
Since you already modified the data array, you can simply return the original ImageData, your modifications will have been made.

// shortened version
(function(){
 const ori = CanvasRenderingContext2D.prototype.getImageData;
 CanvasRenderingContext2D.prototype.getImageData = function(){
  let imageData = ori.apply(this, arguments);
  // modify the Uint8Array
  imageData.data.forEach((v, i, a) => a[i]+=1);
  // return the now modified ImageData
  return imageData;
  };
 })()
 
var ctx = document.createElement('canvas').getContext('2d');
console.log(ctx.getImageData(0,0,1,1));

If you really want to create a new ImageData, then it's

new ImageData(imageData, image.width, image.height);
//             ^^
//           pass the data to fill the new ImageData object

But note that browser support is not great, and that you won't win anything by doing so.

这篇关于覆盖CanvasRenderingContext2D.getImageData()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆