Canvas之使用图像

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 或者 '' 是默认横纵重复。然后将填充或描边后的对象赋值到相关样式中。

平铺样式时,是以画布为原点进行平铺。会出现某些区域显示不完全。

相关推荐
quan263112 分钟前
Vue实践篇-02,AI生成代码
前端·javascript·vue.js
GIS之路13 分钟前
GDAL 读取影像元数据
前端
qb1 小时前
vue3.5.18源码-编译-入口
前端·vue.js·架构
小桥风满袖1 小时前
极简三分钟ES6 - 类与继承
前端·javascript
虫无涯1 小时前
【分享】基于百度脑图,并使用Vue二次开发的用例脑图编辑器组件
前端·vue.js·编辑器
子兮曰1 小时前
🚀99% 的前端把 reduce 用成了「高级 for 循环」—— 这 20 个骚操作让你一次看懂真正的「函数式折叠」
前端·javascript·typescript
wifi歪f1 小时前
📦 qiankun微前端接入实战
前端·javascript·面试
小桥风满袖1 小时前
极简三分钟ES6 - Symbol
前端·javascript
子兮曰1 小时前
🚀Map的20个神操作,90%的开发者浪费了它的潜力!最后的致命缺陷让你少熬3天夜!
前端·javascript·ecmascript 6
NewChapter °1 小时前
如何通过 Gitee API 上传文件到指定仓库
前端·vue.js·gitee·uni-app