HTML5 Canvas教程(11)

2.3 图像数据与 URLs

2.3.1 图像数据

我们在HTML5的canvas中可以使用 getImageData() 方法和图像对象的属性来获取图像中每一

个像素的数据。图像数据中的每个像素都由 red, green, blue, 和 alpha 值来表示。我们就可以用 putImageData() 方法来设置图像的像素值,然后重画经过修改的图像。如:

<script>

  context.drawImage(imageObj, destX, destY);         var imageData = context.getImageData(0, 0, canvas.width, canvas.height);   vardata = imageData.data;

  // 处理像素数据

  context.putImageData(imageData, 0, 0); </script>
注意:方法 getImageData() 要求图像数据存储在 web 服务器上,并且操作这个图像的代码必

须是在同一台服务器上,如果这两条中的任一条不满足的话,将会抛出 SECURITY_ERR 异常。

代码

window.onload = function(){     var imageObj = new Image();     imageObj.onload = function(){         drawImage(this);

    };

    imageObj.src = "darth-vader.jpg";

};

 

function drawImage(imageObj){

    var canvas = document.getElementById("myCanvas");

    var context = canvas.getContext("2d");

 

    var destX = 69;     var destY = 50;

    var sourceWidth = imageObj.width;     var sourceHeight = imageObj.height;

 

    context.drawImage(imageObj, destX, destY);

    var imageData = context.getImageData(0, 0, canvas.width, canvas.height);

    var data = imageData.data;

 

    // 快速遍历所有的像素

    for (var i = 0; i < data.length; i += 4) {

        var red = data[i]; // red         var green = data[i + 1]; // green         var blue = data[i + 2]; // blue

        // i+3 就是 alpha 值

    }

 

    // 另一种遍历像素的方式

    for (var y = 0; y < sourceHeight; y++) {

        // 遍历每一列

        for (var x = 0; x < sourceWidth; x++) {             var red = data[((sourceWidth * y) + x) * 4];             var green = data[((sourceWidth * y) + x) * 4 + 1];             var blue = data[((sourceWidth * y) + x) * 4 + 2];

        }

    }

    // 如果修改了像素数据,就用下面这行代码把图像数据再写回canvas显示

    context.putImageData(imageData, 0, 0); }

2.3.2 反转颜色
如果要反转图像上每个像素的颜色,我们可以用255去减每个像素的 red、 green、 blue 的值,

然后再写回 canvas 中去。
注意:方法 getImageData() 要求图像数据存储在 web 服务器上,并且操作这个图像的代码必

须是在同一台服务器上,如果这两条中的任一条不满足的话,将会抛出 SECURITY_ERR 异常。

效果图

 

代码

window.onload = function(){     var imageObj = new Image();     imageObj.onload = function(){         drawImage(this);

    };

    imageObj.src = "darth-vader.jpg";

};

 

function drawImage(imageObj){

    var canvas = document.getElementById("myCanvas");     var context = canvas.getContext("2d");

 

    var destX = 69;     var destY = 50;

 

    context.drawImage(imageObj, destX, destY);

 

    var imageData = context.getImageData(0, 0, canvas.width,

canvas.height);

    var data = imageData.data;

 

    for (var i = 0; i < data.length; i += 4) {         data[i] = 255 - data[i]; // red         data[i + 1] = 255 - data[i + 1]; // green         data[i + 2] = 255 - data[i + 2]; // blue

        // i+3 是 alpha值

    }

 

    // 覆盖原数据

    context.putImageData(imageData, 0, 0); }

2.3.3 灰度图

要把一个图像转换为灰度图,我们只需要遍历图像中的每个像素,计算像素的亮度值,然后把像素的red、 green、 blue 值都设为亮度值就可以了。

效果图

 

代码

window.onload = function(){     var imageObj = new Image();     imageObj.onload = function(){         drawImage(this);

    };

    imageObj.src = "darth-vader.jpg";

};

 

function drawImage(imageObj){

    var canvas = document.getElementById("myCanvas");

    var context = canvas.getContext("2d");

 

    var destX = 69;     var destY = 50;

 

    context.drawImage(imageObj, destX, destY);

 

    var imageData = context.getImageData(0, 0, canvas.width, canvas.height);

    var data = imageData.data;

 

    for (var i = 0; i < data.length; i += 4) {

        var brightness = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 *

data[i + 2];

 

        data[i] = brightness; // red         data[i + 1] = brightness; // green         data[i + 2] = brightness; // blue

        // i+3 是 alpha 值

    }

 

    // 覆盖原数据

    context.putImageData(imageData, 0, 0); }

2.3.4 获得图像数据 URL
通过 toDataURL() 方法,我们可以得到一个指向当前图像的 64 bit PNG 格式图像文件的

URL. 如 :

<script>

  canvas.toDataURL(); </script>
注意:如果 canvas 包含一个来自其他主机的图像,那么这个 canvas 被称为“脏”的。如果在

这个“脏”的 canvas 上调用 toDataURL() 方法的话,将抛出 SECURITY_ERR 异常。

代码

window.onload = function(){

    var canvas = document.getElementById("myCanvas");     var context = canvas.getContext("2d");

 

    // 画云

    context.beginPath(); // 开始用户定义图形     context.moveTo(170, 80);

    context.bezierCurveTo(130, 100, 130, 150, 230, 150);     context.bezierCurveTo(250, 180, 320, 180, 340, 150);     context.bezierCurveTo(420, 150, 420, 120, 390, 100);     context.bezierCurveTo(430, 40, 370, 30, 340, 50);     context.bezierCurveTo(320, 5, 250, 20, 250, 50);     context.bezierCurveTo(200, 5, 150, 20, 170, 80);     context.closePath(); // 完成图形     context.lineWidth = 5;     context.fillStyle = "#8ED6FF";

    context.fill();

    context.strokeStyle = "#0000ff";

    context.stroke();

 

    // 将canvas图像保存为url(默认是PNG格式)

    var dataURL = canvas.toDataURL(); };

2.3.5 加载图像数据 URL
如果已知一个图像的数据 URL ,我们可以用 drawImage() 方法来把图像输出到 canvas 上。

在这里我们用ajax技术获取图像数据的url,由此url创建一个图像对象,然后用 drawImage() 输出图像。

代码

function loadCanvas(dataURL){

    var canvas = document.getElementById("myCanvas");

    var context = canvas.getContext("2d");

 

    // 从图像url加载图像数据

    var imageObj = new Image();     imageObj.onload = function(){         context.drawImage(this, 0, 0);

    };

 

    imageObj.src = dataURL;

window.onload = function(){

    // 使用 ajax 获取图像数据 url

    var request = new XMLHttpRequest();     request.open("GET", "dataURL.txt", true);     request.onreadystatechange = function(){

        if (request.readyState == 4) { // 确保文档已经做好解析准备             if (request.status == 200) { // 确保能够获取文件                 loadCanvas(request.responseText);

            }

        }

    };

    request.send(null); };

2.3.6 将绘制的图形保存为图像
如果想将在 canvas 中绘制的图形保存为图像文件,我们只需将图像的数据 url 赋值给HTML页

面上的 img 标签的 src 属性,用户就可以通过右键保存的形式把图形保存到本地机器上了。
注意:如果 canvas 包含一个来自其他主机的图像,那么这个 canvas 被称为“脏”的。如果在

这个“脏”的 canvas 上调用 toDataURL() 方法的话,将抛出 SECURITY_ERR 异常。

代码

<head>

    <script>

        window.onload = function(){

            var canvas = document.getElementById("myCanvas");

            var context = canvas.getContext("2d");

 

            // 画云

            context.beginPath(); // 开始用户定义图形             context.moveTo(170, 80);

            context.bezierCurveTo(130, 100, 130, 150, 230, 150);             context.bezierCurveTo(250, 180, 320, 180, 340, 150);             context.bezierCurveTo(420, 150, 420, 120, 390, 100);             context.bezierCurveTo(430, 40, 370, 30, 340, 50);             context.bezierCurveTo(320, 5, 250, 20, 250, 50);             context.bezierCurveTo(200, 5, 150, 20, 170, 80);             context.closePath(); // 完成用户定义图形             context.lineWidth = 5;             context.fillStyle = "#8ED6FF";

            context.fill();

            context.strokeStyle = "#0000ff";

            context.stroke();

 

            // 将canvas图像保存为数据url             var dataURL = canvas.toDataURL();

 

            // 将数据 url 作为 canvasImg 的图像源

            // 这样就可以保存到客户机器上了

            document.getElementById("canvasImg").src = dataURL;

        };

</script>

</head>

<body onmousedown="return false;">

    <canvas id="myCanvas" width="578" height="200" style="display:none;">

    </canvas>

    <img id="canvasImg" alt="Right click to save me!">

</body>