鱼C论坛

 找回密码
 立即注册
查看: 2551|回复: 10

[庖丁解牛] 0 0 7 8 - 用Canvas来玩弄像素

[复制链接]
发表于 2017-3-14 14:30:29 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 不二如是 于 2021-8-11 11:10 编辑

有没有被77的高B格标语震到?!

Canvas不仅能够绘制各种图形、文本、位图还可以直接对像素进行复杂的运算和处理。

简单说,就像图像处理一样,加个滤镜阿、模糊阿、各种LoMo阿。

老规矩还是先创建一个Canvas容器,想复习下的(请点这里)上代码:
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>鱼C工作室</title>
  6.     <style type="text/css">
  7.         html,body{
  8.             height: 100%;
  9.             margin: 333px;
  10.         }
  11.     </style>
  12. </head>
  13. <body>
  14.     <canvas id="fishcCanvas" width="1000" height="999">大兄弟,你的浏览器咋不支持Canvas呢?</canvas>
  15. <script type="text/javascript">
  16.     var canvas = document.getElementById("fishcCanvas");
  17.     var context = canvas.getContext("2d");
  18. </script>
  19. </body>
  20. </html>
复制代码


接下来就从本地加载一张图片吧,就用Fishc官方图片 FishC.zip (550.16 KB, 下载次数: 40, 售价: 2 鱼币)
FishC.png


利用function()来加载图片
  1. var img = new Image();
  2.     img.src = "FishC.png";
  3.     img.onload = function () {
  4.         context.drawImage(img,0,0);

  5.     }
复制代码

效果图:
Snip20170314_818.png


因为在canvas声明中,设置宽高足够,所以图片可以正确显示。

如果初始设置canvas宽高不足,那么可以通过设置 context.drawImage()来增大。

例如,context.drawImage(img.0,0,xxxx,xxxx);来保证加载图片正常显示。


在开始玩弄像素前,还需要从Canvas中获取位图的像素信息

利用getImageData()方法来获取包含每个像素点颜色的字节数据
  1.     img.onload = function () {
  2.         context.drawImage(img,0,0,530,530);

  3.         img = context.getImageData(0,0,530,530);

  4.     }
复制代码

使用getImageData()方法获取了位图的像素节数据后,就可以将这些值传给img对象。

这样就有了可以用来处理的数据流了。

获得这些数据后,就可以开始Hi

遍历这些数据,得到每个像素的R、G、B、Alpha(透明度)。

这个就是位图的四通道RGBA

a642431ca2fab631419658a0042300b0.png


例如有一个800 * 800的位图,就意味:

☆共有800 * 800个像素点。

☆每个像素点都有4个值(R,G,B,A)。

整个位图字节数据的长度就是800 * 800 * 4 。


因为这幅图片是(528*528),凑个整统一设置为530*530。

所以循环的长度就是530 *530 *4
  1. var pixcount = 530 * 530;
  2.         for(var i = 0 ;i < pixcount * 4 ; i += 4)
  3.         {
  4.             var myRed = img.data[i]; //红色
  5.             var myGreen = img.data[i +1 ] //绿色
  6.             var myBlue = img.data[i + 2] //蓝色
  7.             var myAlpha = img.data[i + 3]//透明度
  8.         }
复制代码


每个像素点的数据都是4位,所以遍历条件就是4位一跳,即( i += 4)

现在已尽遍历所有的位图的所有像素点的所有值

然后就可以拿着这些值,愉快的搞事情了~

例如生成灰色图,只要对每个像素点的RGB值都计算平均值,然后把这个值在赋予RGB就可以了。

最后,再把新数据,通过context.putImageData()重绘出来即可
  1. for(var i = 0 ;i < pixcount * 4 ; i += 4)
  2.         {
  3.            /*其他*/

  4.             var myGray = parseInt((myRed + myGreen + myBlue) / 3);//均值获得灰度值
  5.             img.data[i] = myGray;
  6.             img.data[i+1]=myGray;
  7.             img.data[i+2]=myGray;
  8.         }
  9.         
复制代码

效果图:
Snip20170314_819.png


例如半透明,就是第四位值都是128
  1. for(var i = 0 ;i < pixcount * 4 ; i += 4)
  2.         {
  3.            /*其他*/

  4.             img.data[i+3] = 128;
  5.         }
  6.         context.putImageData(img,0,0);
复制代码

效果图:
Snip20170314_820.png


这位鱼油,如果喜欢本帖子,请订阅 专辑-->传送门)(不喜欢更要订阅


官方 Web 课程:

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +3 收起 理由
睦ちゃん她爹 + 5 + 5 + 3 无条件支持楼主!

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-8-19 00:36:05 | 显示全部楼层
交作业~我的天 弄了好久.

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>Title</title>
  6.     <style type="text/css">
  7.         html,body{
  8.             height: 100%;
  9.             margin: 0px;
  10.         }
  11.     </style>
  12. </head>
  13. <body>
  14.     <canvas id="fishcCanvas" width="1000" height="999">你的浏览器不支持canvas.</canvas>
  15.     <script type="text/javascript">
  16.         var canvas = document.getElementById("fishcCanvas");
  17.         var context = canvas.getContext("2d");
  18.         var img = new Image();
  19.         img.src = "FishC.png";
  20.         img.onload = function() {
  21.             context.drawImage(img, 0, 0, 530, 530);
  22.             var imgd = context.getImageData(0, 0, 530, 530);

  23.             var pix = imgd.data;
  24.             for (var i = 0, n = pix.length; i < n; i += 4) {
  25. //                var myRed = pix[i];
  26. //                var myGreen = pix[i + 1];
  27. //                var myBlue = pix[i + 2];
  28. //                var myGray = parseInt((myRed + myGreen + myBlue) / 3);
  29. //                pix[i] = myGray;
  30. //                pix[i + 1] = myGray;
  31. //                pix[i + 2] = myGray;
  32.                 pix[i + 3] = 128;
  33.             }

  34.             context.putImageData(imgd, 0, 0);

  35.         }
  36.     </script>
  37. </body>
  38. </html>
复制代码


11.png

点评

我很赞同!: 5.0
我很赞同!: 5
  发表于 2017-8-19 07:14

评分

参与人数 1荣誉 +6 鱼币 +6 收起 理由
不二如是 + 6 + 6 支持楼主!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-14 15:34:24 From FishC Mobile | 显示全部楼层
这个不经常用吧?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-3-14 15:35:23 | 显示全部楼层
alltolove 发表于 2017-3-14 15:34
这个不经常用吧?

有些简单网页美图,就有利用Canvas搞的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-8-24 00:15:01 | 显示全部楼层
交作业!
078.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-1 14:45:28 | 显示全部楼层
Uncaught DOMException: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.
    at Image.img.onload
这个错误怎么解决啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2018-12-15 22:13:11 | 显示全部楼层
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>Title</title>
  6.     <style type="text/css">
  7.         html,body{
  8.             height: 100%;
  9.             margin: 0px;
  10.         }
  11.     </style>
  12. </head>
  13. <body>
  14.     <canvas id="fishcCanvas" width="1000" height="999">你的浏览器不支持canvas</canvas>
  15.     <script type="text/javascript">
  16.         var canvas = document.getElementById("fishcCanvas");
  17.         var context = canvas.getContext("2d");
  18.         var img = new Image();
  19.         img.src = "1.png";
  20.         img.onload = function() {
  21.             context.drawImage(img, 0, 0, 530, 530);
  22.             img = context.getImageData(0, 0, 530, 530);

  23.             var pixcount = 530*530;
  24.             for (var i = 0, i < pixcount; i += 4) {
  25.                 var myRed = img.data[i];
  26.                 var myGreen = img.data[i + 1];
  27.                 var myBlue = img.data[i + 2];
  28.                 var myAlpha = img.data[i + 3];
  29.                 var myGray = parseInt((myRed + myGreen + myBlue) / 3);
  30.                 img.data[i] = myGray;
  31.                 img.data[i+1]= myGray;
  32.                 img.data[i+1]= myGray;
  33.                 img.data[i+3]=128;
  34.                       
  35.             }

  36.             context.putImageData(img, 0, 0);

  37.         }
  38.     </script>
  39. </body>
  40. </html>
复制代码


为啥我的啥都没有?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-7-8 10:34:40 | 显示全部楼层
好奇怪,跟着老师打就是出不来,楼上鱼油的帖子就可以,搞不懂=。=
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-9 22:28:15 | 显示全部楼层
后半部分都不太理解,看评论改出来了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-9 23:36:58 | 显示全部楼层
拿ws试了,源代码又可以用了,看来是编译器的缘故
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-20 00:33

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表