javascript - 如何在 JavaScript 中对 Canvas 图像进行灰度化?

标签 javascript html canvas grayscale imagedata

我有一个 HTML5 Canvas 内的图像,大小为 28x28 像素。我使用以下代码将 Canvas 的 imageData 获取为 RGBA(红、绿、蓝、alpha)值数组:

canvas = document.getElementById('canvas');
ctx = canvas.getContext("2d");
imgData = ctx.getImageData(0, 0, 28, 28);

现在我想要对图像进行灰度化,以便获得一个包含 784 个值(28x28 像素)的数组,其中每个像素都有一个值(而不是四个)。

我发现了很多不同的灰度公式,有些是乘以 rgb 值,有些只是计算平均值 - 我真的不知道该使用哪一个......

我也被困在获取 784 个值 - 它始终是 3136(因为有 4 个 channel )...

提前致谢!

最佳答案

主要思想是使颜色的红绿和蓝色分量具有相同的值。为此,您需要计算每个像素的亮度。有多种计算亮度的方法。这是其中之一。

window.onload = function() {
  let canvas = document.getElementById("c");

  let ctx = canvas.getContext("2d");
  canvas.width = 50;
  canvas.height = 50;

  let srcImg = document.getElementById("sof");
  ctx.drawImage(srcImg, 0, 0, ctx.canvas.width, ctx.canvas.height);
  let imgData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);
  let pixels = imgData.data;
  for (var i = 0; i < pixels.length; i += 4) {

    let lightness = parseInt((pixels[i] + pixels[i + 1] + pixels[i + 2]) / 3);

    pixels[i] = lightness;
    pixels[i + 1] = lightness;
    pixels[i + 2] = lightness;
  }
  ctx.putImageData(imgData, 0, 0);
}
<canvas id="c"></canvas>
<img src="data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAAZAAD/4QMtaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjMtYzAxMSA2Ni4xNDU2NjEsIDIwMTIvMDIvMDYtMTQ6NTY6MjcgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzYgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTJDRTJFNzlFMzkzMTFFODlEQ0FEQ0NCN0JCMjUxRTEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTJDRTJFN0FFMzkzMTFFODlEQ0FEQ0NCN0JCMjUxRTEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoxMkNFMkU3N0UzOTMxMUU4OURDQURDQ0I3QkIyNTFFMSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoxMkNFMkU3OEUzOTMxMUU4OURDQURDQ0I3QkIyNTFFMSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pv/uAA5BZG9iZQBkwAAAAAH/2wCEABENDQ0ODRIODhIaEQ8RGh8XEhIXHyIXFxcXFyIjGx4dHR4bIyMpKi0qKSM2Njs7NjZBQUFBQUFBQUFBQUFBQUEBEhERFBYUGBUVGBcTFxMXHRcZGRcdLB0dIB0dLDgoIyMjIyg4MjUtLS01Mj09ODg9PUFBQUFBQUFBQUFBQUFBQf/AABEIADQAMgMBIgACEQEDEQH/xACCAAEAAgMBAAAAAAAAAAAAAAAAAwQBAgUGAQEAAwEAAAAAAAAAAAAAAAAAAgMEARAAAQMCAgYHBwUAAAAAAAAAAQACAxEEIRIxQYHREwXwUWGRoSIVcbHBMkJSY2JyIxQ1EQACAgEEAgMBAAAAAAAAAAAAARECITFRYQMSQkGBE3H/2gAMAwEAAhEDEQA/APcIiIAijnnit4zLK7Kwd9TqAVC/fMwxcwtpOJCweZgPkynXt8FC91VN6xlpaxuTp1uzS0nCb0nY6aKOGaOeJssZq1w2g6wfYpFJNNSvki004eGgiIunAiLUvBa4xkPc0HAGvm6kBRn5haiZ9pdRkR6MzhVrvjtVUsksKzWxFzYSfOyuagPXv71vJfyFmS/sSW66YjZXeqrDbcSthcPglcQOFICWuJ1VFfFYr3lzKb9fS64h6m6lIUQ0vZT50fMrNS3y0PZOf638ljKMxJwMbh9J/V7wuso4WRRNEMeUFuJa2gxOk0Ui1ddPCsffC/hl7b+dp+uXy+QiIplZkaVzrQS8G64FBLmOSujN2roa1S9OFSRM8VNcMNKPKOpw5IcvPfuj8NyR23MzPG+dsLmtcC4hozAdhopvT/zv6bU9P/O/ptVX4rE27HG9i39nmKdanapmL/Rm/buVxVoLQQSGTiF5IpirKtKQiIgCIiAIiIAiIgCIiA//2Q=="
  id="sof" />

更新:
替代 lightness计算:

  • Wikipedia (亮度):
    let lightness = parseInt(pixels[i]*.299 + pixels[i + 1]*.587 + pixels[i + 2]*.114);

  • 其他地方(来源未知):
    let lightness = parseInt(3*pixels[i] + 4*pixels[i + 1] + pixels[i + 2] >>> 3);

  • Wikipedia (线性亮度):
    let lightness = 0.2126 * pixels[i] + 0.715 * pixels[i+1] + 0.0722 * pixels[i+2];

关于javascript - 如何在 JavaScript 中对 Canvas 图像进行灰度化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53364140/

相关文章:

javascript - 尝试为 gmail 运行 google API quickstart,按照所有步骤进行操作,但出现错误

javascript - 如果输入文本不在数据列表中则禁用提交

javascript - jQuery - 复选框正在计数,但单击全选复选框时不计数

javascript - 使用 requestAnimationFrame 的简单球动画 HTML5

javascript - 在 html 中使用变量的更好方法

javascript - HTML5 Canvas : Bouncing Balls with Image Overlay

javascript - Canvas drawImage 在本地运行时抛出 INDEX_SIZE_ERR,而不是从网络运行

javascript - 有没有办法检查是否强制执行严格模式?

javascript - 包括需要很长时间才能加载,您可以看到它们正在加载

javascript - Fabric.js - 带有矩形的动态裁剪区域