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

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

相关推荐
To_OC7 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
To_OC8 小时前
LC 17 电话号码的字母组合:我的回溯算法,就是从这道题开窍的
javascript·算法·leetcode
vipbic8 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy8 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志8 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble9 小时前
c端系统,其实更像一个信息展示平台
前端
你怎么知道我是队长10 小时前
JavaScript的变量和数据类型介绍
开发语言·javascript·ecmascript
李姆斯10 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜11 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司11 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能