JS - 如何将图像对象转换为灰度并显示

3

当点击按钮时,它会告诉移动设备去相机。一旦相机拍摄了照片,它将提供图像数据(这被称为数据网址吗?)。这是我处理它的代码:

var imagesrc = "data:image/jpeg;base64," + imageData;

var myimage = new Image(500, 500);
myimage.src = imagesrc;            <---- to populate the object with the colored image
myimage.src = grayscale(myimage);  <---- here I set it to the grayscale image

我想调用一个名为grayscale()的方法,并使其返回已转换为灰度的图像。 我尝试了以下代码:

function grayscale(image){
    var canvasContext = canvas.getContext('2d');
    var imgW = image.width;
    var imgH = image.height;
    canvas.width = imgW;
    canvas.height = imgH;

    canvasContext.drawImage(image, 0, 0);

    var imgPixels = canvasContext.getImageData(0, 0, imgW, imgH);


    for(>var y = 0; y < imgPixels.height; y++){
        for(>var x = 0; x < imgPixels.width; x++){
          var i = (y * 4) * imgPixels.width + x * 4;
          var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
          imgPixels.data[i] = avg;
          imgPixels.data[i + 1] = avg;
          imgPixels.data[i + 2] = avg;
        }
    }

    canvasContext.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);

    dataurl = canvas.toDataURL();
    var newimg = "data:image/jpeg;base64," + dataurl;
    return newimg;
}

但出于某些原因,它不起作用。它只是不能显示灰度图像。我在网上找到了for循环代码并进行了调整。


调整了什么?它最初是做什么的(并且那个方法有效吗)? - Bergi
“不起作用”具体指什么?你进行了一些调试吗?哪里出现了意外行为? - Bergi
嗯,toDataURL已经返回了完整的数据URL,您不需要添加前缀(而且它也不会是JPEG格式)。 - Bergi
3个回答

6
这种方法不能正常工作的原因有几个。你可以开始检查控制台输出来跟踪错误。例如火狐浏览器按"F12"键,会告诉你for(>var ...)是一个问题。 ;)
你在共享给我们的代码之外是否声明了canvasdataurl?不需要为toDataUrl添加前缀...
这是我围绕你的循环打的一个基本html文件,可以将"test.png"转换为灰色。也许你想把它保存到某个地方,在同一个文件夹里放一个png文件,一步步地开始编辑,而不是复制代码。如果你感觉挑战自己,尝试让它通过http://jslint.com/!(你可能需要用while循环替换for循环)。 :)
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Canvas/ImgData Test</title>
</head>

<body>
    <canvas id="output"></canvas>
    <script>
        var cnv = document.getElementById('output');
        var cnx = cnv.getContext('2d');

        function grey(input) {
            cnx.drawImage(myimage, 0 , 0);
            var width = input.width;
            var height = input.height;
            var imgPixels = cnx.getImageData(0, 0, width, height);

            for(var y = 0; y < height; y++){
                for(var x = 0; x < width; x++){
                    var i = (y * 4) * width + x * 4;
                    var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
                    imgPixels.data[i] = avg;
                    imgPixels.data[i + 1] = avg;
                    imgPixels.data[i + 2] = avg;
                }
            }

            cnx.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
        }

        var myimage = new Image();
        myimage.onload = function() {
            grey(myimage);
        }
        myimage.src = "test.png";
    </script>
</body>
</html>

4

我知道你想要把dataURI转换成灰度图像,但是如果你想要将视频反馈本身转换成灰度或者将任何图像转换成灰度,你可以使用以下代码。

.gray {
  filter: grayscale();
}
 <!--hey use this style to show in gray scale. can even use to convert image to grayscale-->
 <video id="camera-stream" class="gray" ></video>


2

不应该将三个颜色分量的平均值作为亮度值,因为它们在亮度上有很大差异(100%的绿色比100%的蓝色要明亮得多)。电视系统(PAL和NTSC)将灰度图像的亮度定义为29.9%红色+58.7%绿色+11.4%蓝色。


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