我在这里找不到错误。我不知道我在哪里错过了一些不让我的代码将图像转换为灰度的东西。如果有人可以尝试这段代码并帮助我找出问题,那将会很有帮助。
<!doctype html>
<html>
<head>
<title>Canvas API</title>
</head>
<body>
<!-- In order to have canvas we need to use the canvas tag -->
<canvas id="c" width="500" height="500"></canvas>
<!-- To use canvas we need to access is from javascript code -->
<script>
var c = document.querySelector("#c"); // grab a canvas with id="c"
var ctx = c.getContext("2d"); // context in which we are using it
var img = new Image();
img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
img.onload = function() {
ctx.drawImage(img, 0, 0);
img.style.display = 'none';
};
var myData = ctx.getImageData(0,0, 500, 500);
console.log(myData);
var grayscale = function(imageData) {
var numPixels = imageData.data.length;
for (var i = 0; i < numPixels; i+=4) {
var avg = 0.34 * imageData.data[i] + 0.5 * imageData.data[i + 1] + 0.16 * imageData.data[i + 2];
imageData.data[i*4+0] = avg;
imageData.data[i*4+1] = avg;
imageData.data[i*4+2] = avg;
// imageData.data[i*4+3] = 255;
}
ctx.putImageData(imageData, 0, 0);
};
grayscale(myData);
</script>
</body>
</html>
最佳答案
您的代码中不只有一个错误。我们已经找到了 4 个:
- 您需要在设置
.src
属性之前设置.onload
处理程序。当图像已在浏览器缓存中时,图像将在设置 .src 属性时加载。当图像已经加载时设置 onload 处理程序不会执行任何操作。 - 您正在获取图像数据并调用
grayscale()
函数,而不检查.onload
处理程序是否已执行,因此当图像不存在时如果没有缓存,您的灰度函数可能会在 onload-handler 将图像绘制到 Canvas 之前执行。如果您想确保在绘制图像后执行灰度转换代码,请将该代码移至ctx.drawImage(img, 0, 0);
之后的 onload-handler 中。 - 在
grayscale
函数中,当您设置imageData.data
时,您将i
乘以4,但当您设置imageData.data
时,您不会将i
乘以4读取数据。这意味着您写入的像素与读取的像素不同。您已经在 for 循环中将i
增加了 4,因此不需要乘法。 - 您正在从远程域 (
mdn.mozillademos.org
) 加载图像。当您将远程图像绘制到 Canvas 上时, Canvas 就会“受到跨源数据的污染”,并且出于安全原因,诸如getImageData
之类的某些功能会被禁用。将图像复制到脚本所在的同一域。 (谢谢@NiettheDarkAbsol)
顺便说一句:除非将新创建的图像节点插入到网站文档的 DOM 树中,否则 new Image()
不会在任何地方显示。您不会在代码中执行此操作。所以 img.style.display = 'none';
是完全没有必要的。
关于javascript - 您好,有人可以帮忙编写 html5 灰度转换代码吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32417408/