视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
HTML5画布Canvas图片抽取、像素信息获取、命中检测
2020-11-27 15:12:23 责编:小采
文档


今天主要介绍canvas中比较强大的功能

比如将画布内容抽取为图片
获取、修改画布的像素信息
以及画布的命中检测
首先我仍然需要创建画布

<canvas id="myCanvas" width=500 height=500></canvas>

图片抽取

首先要明确的一点是
toDataURL()是canvas对象自身的方法而不是环境对象的
这个方法会将canvas的内容抽取为一张图片(base编码)
我们来看一下它的使用方法

canvas转化为图像

我闲着没事用canvas做了一个太极图
js代码如下

let canvas = document.getElementById('myCanvas');
let cxt = canvas.getContext('2d');
let l = canvas.width/2;
const PI = Math.PI;
cxt.translate(l, l);let createTaiChi = () => {
 cxt.clearRect(-l, -l, l, l);
 cxt.arc(0, 0, l, 0, 2*PI, 0);
 cxt.stroke();
 cxt.beginPath();
 cxt.arc(0, -l/2, l/2, -PI/2, PI/2, 0);
 cxt.arc(0, l/2, l/2, 3/2*PI, PI/2, 1);
 cxt.arc(0, 0, l, PI/2, PI*3/2, 0);
 cxt.fill();
 cxt.beginPath();
 cxt.fillStyle = '#fff';
 cxt.arc(0, -l/2, l/7, 0, PI*2, 0);
 cxt.fill();
 cxt.beginPath();
 cxt.fillStyle = '#000';
 cxt.arc(0, l/2, l/7, 0, PI*2, 0);
 cxt.fill();
};

createTaiChi();

再配合css做成一个持续旋转的样子

#myCanvas { 
width: 250px; 
height: 250px; 
margin: 100px; 
animation: rotate 3s linear infinite;
}@keyframes rotate{
 0% { 
 transform: rotateZ(0); 
 }
 100% { 
 transform: rotateZ(360deg); }}

注意这里我设置的css宽高要比canvas本来的宽高小一倍
(这样可以让canvas更清晰一些)


下面我就要将我在canvas画的太极图转化为一张图片
首先要获取canvas的base编码

let data = canvas.toDataURL();console.log(data);

这里我们在控制台打印一下看看它的样子

我们要向将它变成图片,
只需要创建一个img标签,然后将src设置为data即可

let img = document.createElement('img');
img.src = data;document.body.appendChild(img);

这时我们就会发现页面中多了一个静态的太极图
大小与canvas的width/height属性相同 500×500

同源策略

注意这个方法是受同源策略的
比如说我在页面中添加一个本地图片
然后将这张图片画到canvas中

let img = document.getElementsByTagName('img')[0];
cxt.drawImage(img, 0, 0);let data = canvas.toDataURL();

浏览器会报错

我们使用本地服务器的话就可以使用这个方法
证明这个方法受同源策略

像素信息

使用getImageData(x, y, dx, dy)可以获取canvas的像素信息
方法由环境对象调用(我们这里是cxt)
(同样受同源策略)
前两个参数是要获取图像信息的起始坐标,后两个参数就是要获取图像信息的宽高
(类似于矩形绘制函数)
这个方法返回一个ImageData对象(包括像素信息数组data还有宽高width/height)
我们主要用这个对象的data属性

我们画布的大小是500×500
所以获取canvas上所有像素信息就是这样

console.log(cxt.getImageData(0, 0, 500, 500).data);

我们发现这个数组的长度为100w


假如我们的canvas有四个像素点
每个像素点信息有分为RGBA四个方面的值
那么数组长度就应该是4×4 = 16
它们分别是
1R 1G 1B 1A
2R 2G 2B 2A
3R 3G 3B 3A
4R 4G 4B 4A


我们这里的canvas一共有500×500 = 25w个像素点
所以像素信息数组大小为 25w×4 = 100w

我们还可以使用createImageData(width,height)方法
创建一个空白imageData对象

let blankImg = cxt.createImageData(250, 250);
console.log(blankImg);


使用putImageData(imgData, x, y)可以将你的图像像素覆盖原canvas
imgData就是imgData对象,x,y是覆盖的起始坐标
比如说我将我们上面创建的250×250的空白图像覆盖原canvas

cxt.putImageData(blankImg, 0, 0);

命中检测

isPointInPath()可以检测像素点是否在路径区域内
使用方法很简单

cxt.rect(100, 100, 300, 300);if(cxt.isPointInPath(200, 200)){
 cxt.stroke();}

isPointInStroke()用来检测像素点是否在路径上,用法也类似
不过它的兼容性不是很好

下载本文
显示全文
专题