zoukankan      html  css  js  c++  java
  • HTML5边玩边学(3)

    提示建议使用 Chrome 浏览器或者 Firefox 浏览器阅读本文,否则文中的样例程序可能无法看到运行效果。

    一、理解颜色

    我们在电脑屏幕上可以看到色彩斑斓的图像,其实这些图像都是由一个个像素点组成的。那么像素是什么?颜色又是什么呢?(如果您提出这两个问题,您一定是个热爱思考的人)一个像素其实对应着内存中的一组连续的二进制位,由于是二进制位,每个位上的取值当然只能是 0 或者 1 了!这样,这组连续的二进制位就可以由 0 ,1 排列组合出很多种情况,而每一种排列组合就决定了这个像素的一种颜色。先看看下面这幅图

    声明:为本文为原创文章,作者保留所有权利!欢迎转载,转载请注明作者左洸和出处博客园

    我们可以看到这幅图描述了六个像素点,一共由24个小方框组成。

    注意:图中的一个小方框代表一个字节,即8个二进制位。

    因此,每个像素点由四个字节组成。图中也分别标出了这四个字节代表的含义:

    第一个字节决定像素的红色值

    第二个字节决定像素的绿色值

    第三个字节决定像素的蓝色值

    第四个字节决定像素的透明度值

    每一种分颜色值的大小是从 0 到 255(提问:为什么只能到255?) ,透明度的取值:0 代表完全透明,255代表完全不透明

    这样,我们就可以用(255,0,0,255)来表示一个纯红色像素

    在内存中,他是这样的一个32位的串: 11111111 00000000 00000000 11111111

     

    二、操作像素

    了解了颜色和像素的实质,我们就可以对图形进行更加复杂的处理。

    可是,HTML5 目前还没有提供类似 setPixel 或者 getPixel 这样直接操作像素点的方法, 但是我们也有办法

    就是使用 ImageData 对象:

    ImageData对象用来保存图像像素值,它有 width、height和 data 三个属性,其中 data 属性就是一个连续数组,图像的所有像素值其实是保存在 data 里面的。

    data 属性保存像素值的方法和我们在前面图片中看到的一模一样:

    imageData.data[index*4 +0]

    imageData.data[index*4 +1]

    imageData.data[index*4 +2]

    imageData.data[index*4 +3]

    上面取出了 data 数组中连续相邻的四个值,这四个值分别代表了图像中第 index+1 个像素的红色、绿色、蓝色和透明度值的大小。

    注意index 从0 开始,图像中总共有 width * height 个像素,数组中总共保存了 width * height * 4 个数值

    上下文对象 Context 有三个方法用来创建、读取和设置 ImageData 对象,他们分别是

    createImageData(width, height):在内存中创建一个指定大小的 ImageData 对象(即像素数组),对象中的像素点都是黑色透明的,即rgba(0,0,0,0)

    getImageData(x, y, width, height):返回一个 ImageData 对象,这个 IamgeData 对象中包含了指定区域的像素数组

    putImageData(data, x, y):将 ImageData 对象绘制到屏幕的指定区域上

    三、一个简单的图像处理例子

    上面说了这么多,我们用了解的知识来玩玩图像编程,或许有一天我们就要在 Chrome 中玩 PhotoShop 了。

    程序大概是这个样子的:

    1、将一幅图片绘制到一个 canvas 元素上,为了不引发安全错误(Security_ERR:DOM EXCEPTION 18),我用的是我博客顶部的横幅背景图片。你要运行这个例子,可能需要改成自己的图片

    2、有四个滑动条,分别代表 GRBA 四个分量

    3、拖动滑动条,图像中对应的颜色分量就会增加或者减少

    4、如果图像变成透明,就会显示 canvas 元素的背景,我把这个背景设置成了我的头像,呵呵。

    思路:其实就是用 getImageData 方法,将你想改变的那一块区域的像素数组取出来,然后根据你拖动的滑动条和滑动条的数值,来更改那一块区域里所有像素对应颜色分量的值。处理完毕后再用 putImageData 方法绘制到画布上,就是这么简单。

    下面是代码:

    简单的图像处理
    <canvas id="test1" width="507" height="348" style="background-image:url(http://images.cnblogs.com/cnblogs_com/myqiao/262115/r_2204793492575248335.jpg)">你的浏览器不支持 &lt;canvas&gt;标签,请使用 Chrome 浏览器 或者 FireFox 浏览器</canvas>
    红色:<input type="range" min="1" max="100" onchange="colorChange(event,0)"/>
    绿色:<input type="range" min="1" max="100" onchange="colorChange(event,1)"/>
    蓝色:<input type="range" min="1" max="100" onchange="colorChange(event,2)"/>
    透明:<input type="range" min="1" max="100" onchange="colorChange(event,3)"/>
    <script type="text/javascript">
        
    //获取上下文对象
        var canvas = document.getElementById("test1");
        
    var ctx = canvas.getContext("2d");

        
    //画布的宽度和长度
        var width = parseInt(canvas.getAttribute("width"));
        
    var height = parseInt(canvas.getAttribute("height"));

        
    //装入图像
        var image = new Image();
        image.onload 
    =imageLoaded;
        //顶部背景图片
        image.src = "/skins/Valentine/images/banner2.gif";

        
    //用来保存像素数组的变量
        var imageData=null;

        
    function imageLoaded() {
            
    // 将图片画到画布上
            ctx.drawImage(image, 00);

            
    //取图像的像素数组
            imageData = ctx.getImageData(00, width, height);
        }

        
    function colorChange(event,offset){
            imageLoaded();
            
    for (var y = 0; y < imageData.height; y++) {
                
    for (x = 0;x < imageData.width; x++) {
                    
    //index 为当前要处理的像素编号
                    var index = y * imageData.width + x;
                    
    //一个像素占四个字节,即 p 为当前指针的位置
                    var p = index * 4;
                    
    //改变当前像素 offset 颜色分量的数值,offset 取值为0-3
                    var color = imageData.data[p + offset] * event.target.value / 50
                    
    // 颜色值限定在[0..255]
                    color = Math.min(255, color); 
                    
    //将改变后的颜色值存回数组
                    imageData.data[p + offset]=color
                }
            }
            
    //输出到屏幕
            ctx.putImageData(imageData, 00);
        }
    </script>

    你的浏览器不支持 <canvas>标签,请使用 Chrome 浏览器 或者 FireFox 浏览器

    红色:

    绿色:

    蓝色:

    透明:

    四、绘制随机颜色的点

    这个例子是在画布上随机选择一个点,然后再给他一个随机的颜色值,其实用到的方法和上面的例子大同小异,就是需求不同罢了。

    下面是代码和程序实例:

    随机颜色的点
    <canvas id="test2" width="300" height="300" style=" background-color: black">你的浏览器不支持 &lt;canvas&gt;标签,请使用 Chrome 浏览器 或者 FireFox 浏览器</canvas>
    <input type="button" value="画随机点" onclick="interval=setInterval(randomPixel,1);" />
    <input type="button" value="停止" onclick="clearInterval(interval);"/>
    <input type="button" value="清除" onclick="clearCanvas();"/>
    <script type="text/javascript">
        
    //获取上下文对象
        var canvas = document.getElementById("test2");
        
    var ctx = canvas.getContext("2d");

        
    //画布的宽度和长度
        var width = parseInt(canvas.getAttribute("width"));
        
    var height = parseInt(canvas.getAttribute("height"));

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

        
    function randomPixel(){
            
    var x= parseInt(Math.random()*width);
            
    var y= parseInt(Math.random()*height);
            
    var index = y * width + x;
            
    var p = index * 4;

            imageData.data[p 
    + 0= parseInt(Math.random() * 256);
            imageData.data[p 
    + 1= parseInt(Math.random() * 256);
            imageData.data[p 
    + 2= parseInt(Math.random() * 256);
            imageData.data[p 
    + 3=parseInt(Math.random() * 256);
            ctx.putImageData(imageData,
    0,0);
        }

        
    function clearCanvas(){
            ctx.clearRect(
    0,0,width,height);
            imageData 
    = ctx.createImageData(width, height);
        }
    </script>

    你的浏览器不支持 <canvas>标签,请使用 Chrome 浏览器 或者 FireFox 浏览器

    下面是前两篇的链接:

    HTML5边玩边学(1):画布

    HTML5边玩边学(2):基础绘图

    声明:为本文为原创文章,作者保留所有权利!欢迎转载,转载请注明作者左洸和出处博客园 

  • 相关阅读:
    使用helm管理复杂kubernetes应用
    helm repository 相关
    PSQLException: An I/O error occurred while sending to the backend.
    使用helm进行kubernetes包管理
    Slave作为其它Slave的Master时使用
    ext3是对ext2文件系统的一个扩展高性能日志文件系统
    ready是先执行的,load后执行,DOM文档的加载步骤
    jQuery上定义插件并重设插件构造函数
    在PHP与HTML混合输入的页面或者模板中就需要对PHP代码进行闭合
    decode 函数将字符串从某种编码转为 unicode 字符
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/1831003.html
Copyright © 2011-2022 走看看