zoukankan      html  css  js  c++  java
  • [js高手之路] html5 canvas系列教程

    接着上文[js高手之路] html5 canvas系列教程 - 状态详解(save与restore),相信大家都应该玩过美颜功能,而我们今天要讲的就是canvas强大的像素处理能力,通过像素处理,实现反色,黑白,亮度,复古,蒙版,透明等美颜效果.

    getImageData:获取一张图片的像素数据

    cxt.getImageData( x, y, width, height )

    x:图片所在的x坐标

    y: 图片所在的y坐标

    width,height 要获取的像素区域

    返回值是一个对象,对象包括一个data属性, 宽度,高度. data属性是一个巨大的数组,数组中存储的是这张图片的所有像素信息,每四个一组组成一个像素点的信息,如:

    [r1,g1,b1,a1, r2,g2,b2,a2...], r( 红色) g( 绿色) b( 蓝色 ) a( 透明度 )

    putImageData:输出像素图片

    putImageData( 像素对象, x, y )

    注意:getImageData会产生跨域问题,所以你的程序要放在web服务器下,我这里是放在phpstudy下面.

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset='utf-8' />
     5     <style>
     6         #canvas {
     7             border: 1px dashed #aaa;
     8         }
     9     </style>
    10     <script>
    11         window.onload = function () {
    12             var oCanvas = document.querySelector("#canvas"),
    13                 oGc = oCanvas.getContext('2d');
    14 
    15             var oImg = new Image();
    16             oImg.src = './img/mv.jpg';
    17             oImg.onload = function () {
    18                 oGc.drawImage(oImg, 10, 10);
    19                 var imgData = oGc.getImageData(10, 10, 200, 200);
    20                 console.log( imgData );
    21             }
    22         }
    23     </script>
    24 </head>
    25 <body>
    26     <canvas id="canvas" width="500" height="400"></canvas>
    27 </body>
    28 </html>

    我这张图片的尺寸是200 x 200.

    一:反色效果

    算法:把每一个像素的r, g, b颜色取反就行,也就是( 255 - 原来的值 )

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset='utf-8' />
     5     <style>
     6         #canvas {
     7             border: 1px dashed #aaa;
     8         }
     9     </style>
    10     <script>
    11         window.onload = function () {
    12             var oCanvas = document.querySelector("#canvas"),
    13                 oGc = oCanvas.getContext('2d');
    14 
    15             var oImg = new Image();
    16             oImg.src = './img/mv.jpg';
    17             oImg.onload = function () {
    18                 oGc.drawImage(oImg, 10, 10);
    19                 var imgData = oGc.getImageData(10, 10, 200, 200),
    20                     data = imgData.data;
    21                 for( var i = 0; i < data.length; i += 4 ) {
    22                     data[i] = 255 - data[i];
    23                     data[i+1] = 255 - data[i+1];
    24                     data[i+2] = 255 - data[i+2];
    25                 }
    26                 //处理完之后,再次输出
    27                 oGc.putImageData( imgData, 220, 10 );
    28             }
    29         }
    30     </script>
    31 </head>
    32 <body>
    33     <canvas id="canvas" width="500" height="400"></canvas>
    34 </body>
    35 </html>

    二、黑白效果(灰度图)

     将彩色图片转换成黑白图片,原理:求r(data[i]), g(data[i+1]), b(data[i+2])三个通道的平均值,然后把这个平均值赋值给r, g, b

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset='utf-8' />
     5     <style>
     6         #canvas {
     7             border: 1px dashed #aaa;
     8         }
     9     </style>
    10     <script>
    11         window.onload = function () {
    12             var oCanvas = document.querySelector("#canvas"),
    13                 oGc = oCanvas.getContext('2d');
    14 
    15             var oImg = new Image();
    16             oImg.src = './img/mv.jpg';
    17             oImg.onload = function () {
    18                 oGc.drawImage(oImg, 10, 10);
    19                 var imgData = oGc.getImageData(10, 10, 200, 200),
    20                     data = imgData.data, avg = 0;
    21                 for( var i = 0; i < data.length; i += 4 ) {
    22                     avg = ( data[i] + data[i+1] + data[i+2] ) / 3;
    23                     data[i] = avg;
    24                     data[i+1] = avg;
    25                     data[i+2] = avg;
    26                 }
    27                 //处理完之后,再次输出
    28                 oGc.putImageData( imgData, 220, 10 );
    29             }
    30         }
    31     </script>
    32 </head>
    33 <body>
    34     <canvas id="canvas" width="500" height="400"></canvas>
    35 </body>
    36 </html>

    也可以分配rgb的灰度比例

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset='utf-8' />
     5     <style>
     6         #canvas {
     7             border: 1px dashed #aaa;
     8         }
     9     </style>
    10     <script>
    11         window.onload = function () {
    12             var oCanvas = document.querySelector("#canvas"),
    13                 oGc = oCanvas.getContext('2d');
    14 
    15             var oImg = new Image();
    16             oImg.src = './img/mv.jpg';
    17             oImg.onload = function () {
    18                 oGc.drawImage(oImg, 10, 10);
    19                 var imgData = oGc.getImageData(10, 10, 200, 200),
    20                     data = imgData.data, avg = 0;
    21                 for( var i = 0; i < data.length; i += 4 ) {
    22                     avg = data[i] * 0.3 + data[i+1] * 0.3 + data[i+2] * 0.4;
    23                     data[i] = avg;
    24                     data[i+1] = avg;
    25                     data[i+2] = avg;
    26                 }
    27                 //处理完之后,再次输出
    28                 oGc.putImageData( imgData, 220, 10 );
    29             }
    30         }
    31     </script>
    32 </head>
    33 <body>
    34     <canvas id="canvas" width="500" height="400"></canvas>
    35 </body>
    36 </html>

    三、调节亮度的强弱

    在r、g、b、通道上加上一正值就是变亮,加上负值就是变暗

     1 var oImg = new Image();
     2 oImg.src = './img/mv.jpg';
     3 oImg.onload = function () {
     4     oGc.drawImage(oImg, 10, 10);
     5     var imgData = oGc.getImageData(10, 10, 200, 200),
     6         data = imgData.data, avg = 0;
     7     for( var i = 0; i < data.length; i += 4 ) {
     8         data[i] += 30;
     9         data[i+1] += 50;
    10         data[i+2] += 50;
    11     }
    12     //处理完之后,再次输出
    13     oGc.putImageData( imgData, 220, 10 );
    14 }

    变暗:

    data[i] -= 30;
    data[i+1] -= 50;
    data[i+2] -= 50;

    四、复古效果

     将r, g, b按比例混合相加。

     1 var oImg = new Image();
     2 oImg.src = './img/mv.jpg';
     3 oImg.onload = function () {
     4     oGc.drawImage(oImg, 10, 10);
     5     var imgData = oGc.getImageData(10, 10, 200, 200),
     6         data = imgData.data, avg = 0;
     7     for( var i = 0; i < data.length; i += 4 ) {
     8         r = data[i];
     9         g = data[i+1];
    10         b = data[i+2];
    11         data[i] = r * 0.3 + g * 0.4 + b * 0.3;
    12         data[i+1] = r * 0.2 + g * 0.6 + b * 0.2;
    13         data[i+2] = r * 0.4 + g * 0.3 + b * 0.3;
    14     }
    15     //处理完之后,再次输出
    16     oGc.putImageData( imgData, 220, 10 );
    17 }

    五、蓝色蒙版

    蓝色 蒙版就是让图片偏蓝色,将蓝色通道赋值为 r, g, b三原色的平均值,把绿色,红色通道设置为0,其他蒙版效果,只要设置对应的通道平均值,关闭其他通道即可.

     1 var oImg = new Image();
     2 oImg.src = './img/mv.jpg';
     3 oImg.onload = function () {
     4     oGc.drawImage(oImg, 10, 10);
     5     var imgData = oGc.getImageData(10, 10, 200, 200),
     6         data = imgData.data, avg = 0;
     7     for( var i = 0; i < data.length; i += 4 ) {
     8         avg = ( data[i] + data[i+1] + data[i+2] / 3 );
     9         data[i] = 0;
    10         data[i+1] = 0;
    11         data[i+2] = avg;
    12     }
    13     //处理完之后,再次输出
    14     oGc.putImageData( imgData, 220, 10 );
    15 }

    六、透明度

     这个很简单,只要把透明度乘以一个0~1之间的值即可。跟css的opacity一样

     1 var oImg = new Image();
     2 oImg.src = './img/mv.jpg';
     3 oImg.onload = function () {
     4     oGc.drawImage(oImg, 10, 10);
     5     var imgData = oGc.getImageData(10, 10, 200, 200),
     6         data = imgData.data, avg = 0;
     7     for( var i = 0; i < data.length; i += 4 ) {
     8         data[i+3] *= 0.2;
     9     }
    10     //处理完之后,再次输出
    11     oGc.putImageData( imgData, 220, 10 );
    12 }

    七、createImageData:根据图片或者某个宽度与高度创建一个像素区域

    cxt.createImageData( w, h )

    cxt.createImageData( imgData )

    w, h:创建区域的宽度与高度

    imgData: 创建的区域与这个像素区域的宽度和高度相同,imgData就是通过getImageData获取到图片像素的 返回值

    1,根据一个图片的宽度与高度,创建一个透明的红色像素区域

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset='utf-8' />
     5     <style>
     6         #canvas {
     7             border: 1px dashed #aaa;
     8         }
     9     </style>
    10     <script>
    11         window.onload = function () {
    12             var oCanvas = document.querySelector("#canvas"),
    13                 oGc = oCanvas.getContext('2d');
    14 
    15             var oImg = new Image();
    16             oImg.src = './img/mv.jpg';
    17             oImg.onload = function () {
    18                 oGc.drawImage(oImg, 10, 10);
    19                 var imgData = oGc.getImageData(10, 10, 200, 200),
    20                     data = imgData.data,
    21                     imgData2 = oGc.createImageData( imgData ),
    22                     data2 = imgData2.data;
    23                 for( var i = 0; i < imgData2.width * imgData2.height * 4; i += 4 ) {
    24                     data2[i] = 255;
    25                     data2[i+1] = 0;
    26                     data2[i+2] = 0;
    27                     data2[i+3] = 30;
    28                 }
    29                 //处理完之后,再次输出
    30                 oGc.putImageData( imgData2, 220, 10 );
    31             }
    32         }
    33     </script>
    34 </head>
    35 <body>
    36     <canvas id="canvas" width="500" height="400"></canvas>
    37 </body>
    38 </html>

    2,自定一个200 x 200的蓝色透明像素区域

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset='utf-8' />
     5     <style>
     6         #canvas {
     7             border: 1px dashed #aaa;
     8         }
     9     </style>
    10     <script>
    11         window.onload = function () {
    12             var oCanvas = document.querySelector("#canvas"),
    13                 oGc = oCanvas.getContext('2d');
    14 
    15             var imgData = oGc.createImageData( 200, 200 ),
    16                 data = imgData.data;
    17                 for( var i = 0; i < imgData.width * imgData.height * 4 ; i += 4 ){
    18                     data[i] = 0;
    19                     data[i+1] = 0;
    20                     data[i+2] = 255;
    21                     data[i+3] = 100;
    22                 }
    23             oGc.putImageData( imgData, 10, 10 );
    24         }
    25     </script>
    26 </head>
    27 <body>
    28     <canvas id="canvas" width="500" height="400"></canvas>
    29 </body>
    30 </html>

  • 相关阅读:
    Scala 构造器
    Scala 模式匹配
    Scala class & case class & object & case object 对比
    Scala 数据类型 & 类型转换 & 转换精度
    Scala val 和 var 的区别
    Shell脚本统计词频
    Linux基础命令使用总结
    WebGL学习笔记(七):输入和动画
    javaNIO:通道和文件通道 Channel
    javaNIO:缓冲区 Buffer
  • 原文地址:https://www.cnblogs.com/ghostwu/p/7606009.html
Copyright © 2011-2022 走看看