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>

  • 相关阅读:
    SuperMap房产测绘成果管理平台
    SuperMap产权登记管理平台
    Android adb shell am 的用法(1)
    由浅入深谈Perl中的排序
    Android 内存监测和分析工具
    Android 网络通信
    adb server is out of date. killing...
    引导页使用ViewPager遇到OutofMemoryError的解决方案
    adb logcat 详解
    How to send mail by java mail in Android uiautomator testing?
  • 原文地址:https://www.cnblogs.com/ghostwu/p/7606009.html
Copyright © 2011-2022 走看看