您的位置:首页 > Web前端 > HTML5

【初识HTML5】(4) : 图像

2015-02-16 15:46 162 查看
HTML5提供了大量的方法来画图以及操作图像数据。直奔主题吧~

1.画图方法的3种不同的参数

var canvas = document.getElementById('canvas'),
context = canvas.getContext('2d'),
image = new Image();
image.src = 'fence.png';
image.onload = function(e) {
context.drawImage(image, 0, 0);
};




这里最主要的是用到了drawImage(), 这个方法有3种不同的参数:

drawImage(image, dx, dy)

drawImage(image, dx, dy, dw, dh)

drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)



通过上图,我们对每个参数应该有了一定的了解了吧?

第一个方法主要作用是:将一张图画在画布的指定位置

第二个方法主要作用是:将一张图画以指定的宽和高画在画布的指定位置

第三个方法主要作用是:将一张图或它的一部分以指定的宽和高画在画布的指定位置。

这里要提醒大家的是,画布可以画图、画布、视频。

2.在画布区域外画画

我们在使用drawImage()时可以通过指定负数,调整图片的位置,从而在画布上显示我们所要的效果:



图中亮部就是画布的范围,而灰色部分则是超出画布区域的图片显示。通过这个原理,相信大家自然就会想到一种效果:放大镜。没错!我们还是先来看一下上面的效果是如何实现的吧:

function drawImage() {
var w = canvas.width,
h = canvas.height,
sw = w * scale,
sh = h * scale;
context.clearRect(0, 0, w, h);
context.drawImage(image, -sw/2 + w/2, -sh/2 + h/2, sw, sh);
}


3.在当前画布上显示另一个画布的内容

还是以上图为例,我们可以用如下方法:

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var image= new Image();
image.src='xxx.jpg';
context.drawImage(image,0,0);
context.drawImage(canvas,0,0,1000,1000)


我们仔细想想,其实这个方法还是有值得推敲的地方。为什么呢?因为浏览器等于每张图都要画两次,效率不是很高。在实际浏览器实际执行中,其实它会创建一个看不见的画布来放大图片。然后再重新放到当前画布。不过在图片缩放的应用中,我们还是可以使用的。

大家注意,此时我们引出了一个新的概念叫:Offscreen Canvases (屏幕外画布)

3.Offscreen Canvases (屏幕外画布)

var canvas = document.getElementById('canvas'),
context = canvas.getContext('2d'),
offscreenCanvas = document.createElement('canvas'),
offscreenContext = offscreenCanvas.getContext('2d'),
...
// 设置offscreenCanvas的参数
offscreenCanvas.width = canvas.width;
offscreenCanvas.height = canvas.height;
...
// 向offscreenCanvas画画
offscreenContext.drawImage(anImage, 0, 0);
...
// 在当前画布上画出offscreenCanvas的内容
context.drawImage(offscreenCanvas, 0, 0,
offscreenCanvas.width, offscreenCanvas.height);


关于offscreenCanvas 我们注意两点:

1.offscreenCanvas默认大小是300px*150px 和普通画布的默认大小一样

2.这是一种思路,我们可以通两个画布间的交互,从而减少工序。应该好好推敲和使用。

4.ImageData对象操作

<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.fillStyle = "red";
context.fillRect(10, 10, 50, 50);
function copy() {
var imgData = context.getImageData(10, 10, 50, 50);
context.putImageData(imgData, 10, 70);
}
</script>
<button onclick="copy()">Copy</button>
</body>
</html>


以上我们用到了两个主要的方法:

getImageData(in double sx, in double sy, in double sw, in double sh)返回 ImageData 对象,该对象拷贝了画布指定矩形的像素数据。

x 开始复制的左上角位置的 x 坐标。

y 开始复制的左上角位置的 y 坐标。

width 将要复制的矩形区域的宽度。

height 将要复制的矩形区域的高度。

我们在进一步深入下去之前,我们先来看看一些你必须知道的事~

对于 ImageData 对象中的每个像素,都存在着四方面的信息,即 RGBA 值:

R - 红色 (0-255)

G - 绿色 (0-255)

B - 蓝色 (0-255)

A - alpha 通道 (0-255; 0 是透明的,255 是完全可见的)

color/alpha 以数组形式存在,并存储于 ImageData 对象的 data 属性中。

如何遍历所有像素的RGBA呢?

for (var i=0;i<imgData.data.length;i+=4)
{
imgData.data[i]=255-imgData.data[i];
imgData.data[i+1]=255-imgData.data[i+1];
imgData.data[i+2]=255-imgData.data[i+2];
imgData.data[i+3]=255;
}


这个方法在遍历像素的基础上,做了一个颜色反转的效果:

red=255-old_red;

green=255-old_green;

blue=255-old_blue;

大家可以到网上搜相关的滤镜教程来丰富自己的画布,滤镜运用的就是上述的原理,感兴趣的朋友可以分享自己的滤镜代码哟~

相信我们已经掌握了ImageDate的一些实质性的东西了,既然我们拿到了数据,就一定会有放回数据的命令,没错:

putImageData(in ImageData imagedata, in double dx, in double dy, in optional double dirtyX, in double dirtyY, in double dirtyWidth, in double dirtyHeight);将图像数据(从指定的 ImageData 对象)放回画布上。

imgData 规定要放回画布的 ImageData 对象。

dx ImageData 对象左上角的 x 坐标,以像素计。

dy ImageData 对象左上角的 y 坐标,以像素计。

dirtyX 可选。水平值(x),以像素计,在画布上放置图像的位置。

dirtyY 可选。水平值(y),以像素计,在画布上放置图像的位置。

dirtyWidth 可选。在画布上绘制图像所使用的宽度。

dirtyHeight 可选。在画布上绘制图像所使用的高度。



这里要提醒大家一下。有的时候,比如放大镜程序,有些朋友会频繁地调用getImageData()获取图像,这在手机上或者平板上会很大影响交互。比较好的解决办法是,只调用一次getImageData(),然后通过putImageData()将相关的矩形拷贝到画布上。

5.剪切选区

clip() 方法从原始画布中剪切任意形状和尺寸。

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.rect(50,20,200,120);
context.stroke();
context.clip();
context.fillStyle="green";
context.fillRect(0,0,150,100);




关于clip() 我们一般会配合 save()、restore()来使用。因为一旦我们clip()之后,你再进行clip()的话是基于上一个选区,换言之你的选区会越来越小。除非你要的是这种效果,否则我们可以这么来操作:

……

context.save();

//do somethong

context.clip();

restore()

//do something;

context.clip();

…….
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  html5 sam走起