Canvas之使用图像
js
const img = new Image();
img.src='exercises/imgs/01.png'
img.onload = function () {
ctx.drawImage(img, 0, 90, 400, 220);
};
js
const img = new Image();
img.src='exercises/imgs/01.png'
img.onload = function () {
ctx.drawImage(img, 44, 0, 200, img.height,100,(400-img.height)/2,200,img.height);
};
Canvas 可以引入图像,可以是image,video,canvas 格式。image 可以是图片路径或者是base64格式。
当我们创建了一个图片之后,需要在图片加载之后进行绘制,因为图片的绘制速度远大于图片的加载速度。
可以只放图像坐标,就显示原大小。可以放入图像宽高,就表示显示在画布上的大小。还可以加入两组数据,前一组表示原图片截图坐标,大小,后一组表示放在画布上的坐标,大小。当然可能经过了两次缩放。
js
const video = document.querySelector('video');
video.addEventListener('play', function () {
draw();
})
ctx.arc(200, 200, 150, 0, Math.PI * 2);
// ctx.filter = 'invert(0.8)';
ctx.clip();
function draw() {
ctx.clearRect(0, 0, 400, 400);
if (video.currentTime < 1) {
ctx.filter = "blur(5px)";
} else {
ctx.filter = "none";
}
ctx.drawImage(video, 0, 0, 400, 400);
requestAnimationFrame(draw);
}
视频可以通过抓取视频中的每一帧来得到图片,引入到 Canvas 中。同样,可以在视频播放之后进行图片的获取。
js
canvas1 = document.createElement('canvas');
document.body.append(canvas1);
canvas1.width = 200;
canvas1.height = 200;
const ctx = canvas1.getContext('2d');
//绘制同心圆
for (let i = 0; i < 5; i++) {
ctx.beginPath();
ctx.arc(100, 100, 20 * (i + 1), 0, Math.PI * 2);
ctx.stroke();
}
js
canvas2 = document.createElement('canvas');
document.body.append(canvas2);
canvas2.width = 400;
canvas2.height = 400;
const ctx = canvas2.getContext('2d');
ctx.beginPath();
ctx.drawImage(canvas1, 0, 0, 100, 100, 150, 150, 100, 100);
Canvas 可以作为图像源引入 Canvas ,类似于图像的引入。
js
const btn = document.querySelectorAll('button')[0];
btn.onclick = function () {
const url = canvas1.toDataURL();
const a = document.createElement('a');
a.href = url;
a.download = 'canvas.png';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
当我们想下载 Canvas 图像时,可以右键下载,和正常图片一样。也可以进行编程式下载。
由于浏览器限制用户访问本地文件资源,所以可以采取点击链接下载的方式来进行。首先创建一个 a 元素,将它的地址设置为 canvas 的 base64 格式。然后设置为下载模式,最后模拟元素点击,就可以下载了。toDataURL() 默认为 png 格式,可以通过传参改变格式。
js
const img = new Image();
img.crossOrigin = 'anonymous';//允许跨域
img.src = 'exercises/imgs/01.png';
img.onload = function () {
ctx.drawImage(img, 0, 0);
}
使用这种模式可能会出现同源问题。是由于浏览器只能使用本地文件资源或者本地服务器。如果使用其他路径资源,可能导致画布被污染。可以设置 crossOrigin ,然后使用本地服务器。
js
const img = new Image();
img.src = '/girl.jpg';
img.onload = function () {
ctx.drawImage(img, 50, 0, 300, 400);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
for (let i = 0; i < imageData.data.length; i += 4) {
const r = imageData.data[i];
const g = imageData.data[i + 1];
const b = imageData.data[i + 2];
const a = imageData.data[i + 3];
}
ctx.putImageData(imageData, 0, 0);
};
我们在引入一个图片之后可以拿到一个区域的像素对象。里面包含了像素宽度,高度和像素值的数组。因为一个像素包含四个通道,所以分成四份。
所有的像素并不是又分别形成一个数组,而是依次放到原数组中。所以只存在一个一维数组。我们可以得到某一个坐标的像素值。
要想操作每个像素,可以使用 for 循环,不过要每四个一组。ctx.getImageData(x , y , width , height)可以进行获取,然后进行设置。之后需要使用 ctx.putImageData(imageData,x,y) 才能正常应用设置的像素值变化。比如灰度,反差色等。
js
const img = new Image();
img.src = 'exercises/imgs/03.png';
img.onload = function () {
const pattern = ctx.createPattern(bgCanvas, 'repeat');
const pattern2 = ctx.createPattern(img, '');
ctx.strokeStyle = pattern;
ctx.fillStyle = pattern2;
ctx.lineWidth = 30;
ctx.rect(15, 15, 330, 330);
ctx.stroke();
ctx.fill()
};
可以引入图像源来作为背景,和之前一样,可以是img,video,canvas等。可以选择进行填充或者描边。
先使用 ctx.createPattern(imgSource , repetition) 来创建一个图案对象,第二个参数必须填写,填 null 或者 '' 是默认横纵重复。然后将填充或描边后的对象赋值到相关样式中。
平铺样式时,是以画布为原点进行平铺。会出现某些区域显示不完全。