【初识HTML5】(4) : 图像

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();
…….

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值