在鼠标悬停期间显示 canvas 中的值

Display value in canvas during mouseover

尊敬的 JavaScript 用户,

我需要能够:

  1. 加载 png 图像并将其显示在 canvas
  2. 存储其原始像素值
  3. 转换像素值以表示新颜色
  4. 当用户将光标移到图像上时在屏幕上显示原始值

这听起来有点奇怪,但我的实时系统中的原始像素值将包含我需要保留的编码数据,并在随后执行任何像素值操作后显示在屏幕上。我需要在初始加载图像后更改颜色映射以使其更赏心悦目,但需要在屏幕上显示原始值。

我的方法在 canvas 上显示一些简单的几何形状时有效,但一旦我尝试使用 png 图像,它就会停止工作。谁能帮我理解这是为什么?

这里有一个适用于简单形状的示例(没有像素值转换): http://jsfiddle.net/DV9Bw/1219/

如果您注释掉第 24 - 29 行,并取消注释第 32 - 40 行,以便它以 png 格式加载,它将停止工作。 png 文件加载,但数据值不再显示在屏幕上。

欢迎就我使用 png 时为什么会出现问题提出任何建议;任何关于如何修复它的建议都将更加受欢迎!

非常感谢您的帮助。

大卫

function findPos(obj) {
    var curleft = 0, curtop = 0;
    if (obj.offsetParent) {
        do {
            curleft += obj.offsetLeft;
            curtop += obj.offsetTop;
        } while (obj = obj.offsetParent);
        return { x: curleft, y: curtop };
    }
    return undefined;
}

function rgbToHex(r, g, b) {
    if (r > 255 || g > 255 || b > 255)
        throw "Invalid color component";
    return ((r << 16) | (g << 8) | b).toString(16);
}


var example = document.getElementById('example');
var context = example.getContext('2d');


// The squares works
context.fillStyle = "rgb(255,0,0)";
context.fillRect(0, 0, 50, 50);
context.fillStyle = "rgb(0,0,255)";
context.fillRect(55, 0, 50, 50);
// End of squares


/*
// Replacing the squares section above with this 
// png image stops the mouseOver from working, Why?
var imageObj = new Image();
imageObj.onload = function() {
  context.drawImage(imageObj, 0, 0, imageObj.width, imageObj.height, 0, 0, imageObj.width*4, imageObj.height*4);
};
imageObj.src = 'http://dplatten.co.uk/mouseOver/skin_dose_map.png';
*/


var originalValues = new Array();
originalValues = context.getImageData(0,0,280,360).data;

$('#example').mousemove(function(e) {
    var pos = findPos(this);
    var x = e.pageX - pos.x;
    var y = e.pageY - pos.y;
    var coord = "x=" + x + ", y=" + y;
    var c = this.getContext('2d');
    var r = originalValues[(y*280 + x)*4];
    var g = originalValues[(y*280 + x)*4+1];
    var b = originalValues[(y*280 + x)*4+2];
    $('#status').html(coord + "<br>" + r + "," + g + "," + b);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="example" width="280" height="360"></canvas>
<div id="status"></div>

问题有两个

首先,这两行:

var originalValues = new Array();
originalValues = context.getImageData(0,0,280,360).data;

正在 运行 绘制图像之前,因为它仍在等待图像加载。

然后,如果将 context.getImageData() 移动到 imgObject.onload 函数内部,您将 运行 陷入另一个问题,即您不能 运行 getImageData() 在与 运行 脚本文件不在同一位置的图像上。您将收到以下消息:

Uncaught SecurityError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.

如果您将图像放在同一台服务器上并将 getImageData() 调用移到 onload 函数中,它应该可以工作。