鱼C论坛

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

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

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

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

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

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

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

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

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

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

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


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

    }
效果图:
Snip20170314_818.png


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

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

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


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

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

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

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

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

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

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

这个就是位图的四通道RGBA

a642431ca2fab631419658a0042300b0.png


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

[b]☆共有800 * 800个像素点。

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

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


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

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

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

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

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

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

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

            var myGray = parseInt((myRed + myGreen + myBlue) / 3);//均值获得灰度值
            img.data[i] = myGray;
            img.data[i+1]=myGray;
            img.data[i+2]=myGray;
        }
        
效果图:
Snip20170314_819.png


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

            img.data[i+3] = 128;
        }
        context.putImageData(img,0,0);
效果图:
Snip20170314_820.png


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


官方 Web 课程:

评分

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

查看全部评分

本帖被以下淘专辑推荐:

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

使用道具 举报

发表于 2017-8-19 00:36:05 | 显示全部楼层
交作业~我的天 弄了好久.
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        html,body{
            height: 100%;
            margin: 0px;
        }
    </style>
</head>
<body>
    <canvas id="fishcCanvas" width="1000" height="999">你的浏览器不支持canvas.</canvas>
    <script type="text/javascript">
        var canvas = document.getElementById("fishcCanvas");
        var context = canvas.getContext("2d");
        var img = new Image();
        img.src = "FishC.png";
        img.onload = function() {
            context.drawImage(img, 0, 0, 530, 530);
            var imgd = context.getImageData(0, 0, 530, 530);

            var pix = imgd.data;
            for (var i = 0, n = pix.length; i < n; i += 4) {
//                var myRed = pix[i];
//                var myGreen = pix[i + 1];
//                var myBlue = pix[i + 2];
//                var myGray = parseInt((myRed + myGreen + myBlue) / 3);
//                pix[i] = myGray;
//                pix[i + 1] = myGray;
//                pix[i + 2] = myGray;
                pix[i + 3] = 128;
            }

            context.putImageData(imgd, 0, 0);

        }
    </script>
</body>
</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 | 显示全部楼层
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        html,body{
            height: 100%;
            margin: 0px;
        }
    </style>
</head>
<body>
    <canvas id="fishcCanvas" width="1000" height="999">你的浏览器不支持canvas</canvas>
    <script type="text/javascript">
        var canvas = document.getElementById("fishcCanvas");
        var context = canvas.getContext("2d");
        var img = new Image();
        img.src = "1.png";
        img.onload = function() {
            context.drawImage(img, 0, 0, 530, 530);
            img = context.getImageData(0, 0, 530, 530);

            var pixcount = 530*530;
            for (var i = 0, i < pixcount; i += 4) {
                var myRed = img.data[i];
                var myGreen = img.data[i + 1];
                var myBlue = img.data[i + 2];
                var myAlpha = img.data[i + 3];
                var myGray = parseInt((myRed + myGreen + myBlue) / 3);
                img.data[i] = myGray;
                img.data[i+1]= myGray;
                img.data[i+1]= myGray;
                img.data[i+3]=128;
                      
            }

            context.putImageData(img, 0, 0);

        }
    </script>
</body>
</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-11-22 09:11

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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