• 【canvas学习笔记八】像素操作


    ImageData对象

    ImageData对象包含了一个区域内的canvas的像素信息。它包含以下可读属性:

    width
    canvas的宽度,单位是像素。
    height
    canvas的高度,单位是像素。
    data
    一个Uint8ClampedArray的一维数组,包含了每个像素的RGBA值。

    什么是Uint8ClampedArray?这个数组里的数值是8位的整型,而且值得范围在0和255之间。任何不在[0, 255]之间的数都会变成[0, 255]之间最接近的那个整型数。
    0到255之间,那记录的自然是RGBA颜色数值啦。这个data数组是这样排列的,data[0]是第一排第一列的像素R通道的数值,data[1]第一排第一列的像素G通道的数值,data[3]是第一排第一列的像素的Alpha通道的数值。而data[4]是第一排第二列的像素的R通道数值,以此类推。
    比如说,第50排第200列的像素的蓝色通道的值:

    blueComponent = imageData.data[((50 * (imageData.width * 4)) + (200 * 4)) + 2];

    另外,data也有length属性,就是data数组的长度。

    创建ImageData对象

    有两种方法创建ImageData:

    var myImageData = ctx.createImageData(width, height);

    var myImageData = ctx.createImageData(anotherImageData);

    注意啦,方法二是不会把data属性复制过去的,仅仅是复制了宽度和高度,data数组里的像素信息都是透明黑的,也就是都是0。

    获取像素信息

    可以用getImageData()方法获取像素信息。

    var myImageData = ctx.getImageData(left, top, width, height);

    top和left就是所截取的画布部分的左上角坐标。

    Tip:
    超过画布区域返回的像素信息都是透明黑,也就是都是0。

    例子

    var img = new Image();
    img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    img.onload = function() {
      ctx.drawImage(img, 0, 0);
      img.style.display = 'none';
    };
    var color = document.getElementById('color');
    function pick(event) {
      var x = event.layerX;
      var y = event.layerY;
      var pixel = ctx.getImageData(x, y, 1, 1);
      var data = pixel.data;
      var rgba = 'rgba(' + data[0] + ', ' + data[1] +
                 ', ' + data[2] + ', ' + (data[3] / 255) + ')';
      color.style.background =  rgba;
      color.textContent = rgba;
    }
    canvas.addEventListener('mousemove', pick);
    

    结果

    image
    鼠标滑过就会显示rgba值。

    绘制像素

    ctx.putImageData(myImageData, dx, dy);

    这个方法可以传入一个ImageData对象,然后把ImageData对象中的像素信息都画出来。dx, dy是绘制的左上角坐标。
    比如我们可以逐一改变ImageData对象中的值,从而改变了整个图象的颜色,再把它画出来。
    这有什么用呢?对于要对像素进行的操作来说,这很方便。比如反色、去色等操作。

    例子

    var img = new Image();
    img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
    img.onload = function() {
      draw(this);
    };
    
    function draw(img) {
      var canvas = document.getElementById('canvas');
      var ctx = canvas.getContext('2d');
      ctx.drawImage(img, 0, 0);
      img.style.display = 'none';
      var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
      var data = imageData.data;
        
      var invert = function() {
        for (var i = 0; i < data.length; i += 4) {
          data[i]     = 255 - data[i];     // red
          data[i + 1] = 255 - data[i + 1]; // green
          data[i + 2] = 255 - data[i + 2]; // blue
        }
        ctx.putImageData(imageData, 0, 0);
      };
    
      var grayscale = function() {
        for (var i = 0; i < data.length; i += 4) {
          var avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
          data[i]     = avg; // red
          data[i + 1] = avg; // green
          data[i + 2] = avg; // blue
        }
        ctx.putImageData(imageData, 0, 0);
      };
    
      var invertbtn = document.getElementById('invertbtn');
      invertbtn.addEventListener('click', invert);
      var grayscalebtn = document.getElementById('grayscalebtn');
      grayscalebtn.addEventListener('click', grayscale);
    }
    

    invert()反色函数将RGB通道的值用255减去,grayscale()去色函数将RGB通道的值进行平均,从而使颜色变成灰色。

    结果

    image

    点击grayscale按钮图片会变成灰色,点击invert按钮图片会反色。
    可以把代码放进codepen里看看效果如何。

    保存图片

    canvas可以将画布保存成图片链接,图片链接可以用于标签或者下载。

    canvas.toDataURL('image/png')
    默认转换成的格式是png。
    canvas.toDataURL('image/jpeg', quality)
    也可以是别的图片格式。quality是图片品质,数值是0~1。0是最差的品质,1是最佳的品质。

    也可以生成二进制对象:

    canvas.toBlob(callback, type, encoderOptions)

  • 相关阅读:
    Vue让水平滚动条(scroll bar)固定在浏览器的底部,并且同轴联动
    vue横向滚动条,初始化位置
    VUE父子组件传值,以及子组件调用父组件方法
    获取shell脚本所在路径而非执行路径
    免重装完整迁移ubuntu18.04系统方法
    auth.log大量出现pam_unix(cron:session): session opened for user root by (uid=0)解决办法
    禁用vim的visual模式方便拖选
    ssh端口反向代理与内网穿透
    mysql查询时将时间戳转换为时间格式
    浏览器打印控件分享
  • 原文地址:https://www.cnblogs.com/-867259206/p/7448270.html
Copyright © 2020-2023  润新知