canvas实现炫酷的一键抠图和背景替换
演示地址
代码仓库
关键技术
canvas api
、 element-ui (el-color-picker、el-upload)
原理解析
1. 用户从本地上传一张图片
我们拿到图片数据并在页面渲染出来,这一步用到了elementui的el-upload
el-upload.avatar-uploader(ref="logoUpload",accept="image/*",action="#",:auto-upload="false",:on-change="handleStatusChange"
)el-button(size="small", type="primary") 点击上传
这里实际上不需要真正上传到服务器,只需要获取到图片的在内存中的url
handleStatusChange(file) {// console.log(file);this.originImg = URL.createObjectURL(file.raw);
},
拿到url之后可以先把图片用img
标签渲染在页面上,这样做的目的是为了获取图片的实际尺寸,方面我们等比例缩放在我们的canvas
上。
// 图片加载完成loadImg(e) {const img = e.target;const width = img.offsetWidth;const height = img.offsetHeight;this.imgWidth = width;this.imgHeight = height;this.canHeight = (height / width) * this.canWidth;}
canvas的width可以根据外层容器来获取
this.$nextTick(() => {const contentWidth = document.querySelector(".origin-box").offsetWidth;this.canWidth = Math.min(contentWidth - 12, this.canWidth);
});
2. 绘制canvas
绘制图片到canvas,这一步比较简单,
//这里需要缩放一下,因为我们的画布已经被缩放了
this.originCtx.scale(this.canWidth / width, this.canWidth / width);
this.originCtx.drawImage(img, 0, 0);
3. 选中颜色
点击canvas,我们可以拿到该点上的颜色值,获取方式
ctx.getImageData(targetX,targetY,1,1)
拿到的是imagedate对象,{data, width, height}
,data即为我们要的颜色值。
4. 遍历原图片的颜色值,匹配到选中颜色之后,做对应颜色的替换即可
核心api: getImageData putImageData
//获取data
const data = this.imageData.data || [];
//遍历并替换
for (let i = 0; i < data.length; i += 4) {const similar = this.isSimilar(_fromColor, data.slice(i, i + 4));if (similar) {data[i] = _toColor[0];data[i + 1] = _toColor[1];data[i + 2] = _toColor[2];data[i + 3] = _toColor[3] * 255;}}//绘制到目标容器上this.transCtx.putImageData(this.imageData, 0, 0);
isSimilar
方法用来判断两个颜色是否相似或相等,这个可以通过参数调整(类似于ps的容差概念),容差值越小,匹配越精准。
颜色值是rgba格式的,即4个数组为一组,数值都在[0,255]之间,由于el-picker返回的rgba,透明度用的是【0,1】表示的,所以要转换到0-255区间
5. undo&redo
撤销、前进、后退功能还是很有必要的,重复替换操作,可返回历史操作步骤。
创建一个队列(这里用数组代替),每次有新的数据变化添加到队列里,用unshift
表示入列pop
从队列后面删除。可以设置上限10,队列过大会占用较大内存,不建议设置过大。
维护一个index,理解成指针,表示当前回退的数据在队列中的位置。
undo() {this.index++;this.redrawImg();
},
redo() {this.index--;this.redrawImg();
},
redrawImg() {const preImageData = JSON.parse(this.imgStock[this.index]).data;this.imageData = this.transCtx.createImageData(this.canWidth,this.canHeight);for (let i = 0; i < this.imageData.data.length; i++) {this.imageData.data[i] = preImageData[i];}this.transCtx.putImageData(this.imageData, 0, 0);
},
需要注意的细节:当回退到某一条历史记录,比如index=5,这时候再执行手动操作替换,此时就“穿越”了,需要把index = 5之前的历史都移除。(可能描述有点绕~)
至此,就完成了核心功能了~
TODO LIST
- 增加边缘识别,去除毛边
- 增加容差选项
- 尝试视频抠图和替换
- 。。。
演示地址
代码仓库
欢迎提意见&star!
canvas实现炫酷的一键抠图和背景替换相关推荐
- html发光loading,Canvas 制作炫酷发光loading动画
Canvas制作炫酷发光loading动画 /* NOTE: The styles were added inline because Prefixfree needs access to your ...
- 全自动抠图换背景软件下载_手机一键抠图换背景,用这个APP就是这么简单
用手机快速抠图换背景,并且抠的是'人像',我个人觉得相对较'快速'的抠图方法,是使用马卡龙玩图这个app,它绝对是一键抠图换背景的神器. 用这个软件抠图有几个前提条件: 1.所抠的图必须是人像: 2. ...
- 如何一键抠图换背景,这三个工具告诉你
随着科技的不断进步,我们的生活变得越来越便捷.特别是人工智能技术的发展,让许多以前需要我们手动完成的事情,现在都能通过软件轻松地实现.比如我们可以在家呆着就逛遍全世界,大家一定很好奇这怎么才能做到吧. ...
- H5炫酷特效系列2——canvas特效-炫酷的心
之前已经有了一个满屏幕红心的案例,这次带来一个更加炫酷的心型炫酷动效,直接上图,有兴趣的就继续往下看,没兴趣直接过. 屏幕上眼花缭乱的心,不停的冲击着你的视线,让那些少女心砰砰直跳,绝对表白利器,同志 ...
- html5 星空扩散效果,HTML5 canvas实现炫酷旋转银河系星空背景特效解析
简要教程 这是一款html5 canvas炫酷旋转银河系星空背景特效.该特效通过canvas来绘制银河系星盘,并制作星系旋转的效果,非常炫酷. 使用方法 HTML结构 该旋转银河系星空背景特效的HTM ...
- Canvas绘制炫酷的火焰风暴动画
今天给大家分享一个用Canvas写的火焰风暴动画,实现效果如下: 怎么样,场面是不是很壮观,下面是代码实现,欢迎大家复制粘贴和吐槽. <!DOCTYPE html> <html la ...
- python(remove_bg)一键抠图换背景 智能抠图
缘起 基于 remove.bg API . 可实现突破一键抠图和换背景 当然换背景是基于 PIL 官方文档 install 我们要 实现这2个功能要安装2个模块和一个API-KEY moudel: r ...
- php+js+背景特效,基于canvas+html5炫酷星空背景动画特效
[温馨提示]源码包解压密码:www.youhutong.com 效果图: 描述说明: Warp drive是一个轻量级的jQuery插件.可以帮助您创建一个很酷的交互式星空背景特效,这个星空背景特效可 ...
- 日常总结:Vue实现一个炫酷的代码瀑布流背景
先看一下效果: 代码奉上: <template><canvas id="canvas" /> </template><script> ...
最新文章
- 设计模式四:简单工厂
- 神经网络 | 神经网络概述及发展史
- 教育部计算机科学,关于批准计算机科学与技术专业教学改革与实践项目立项的通知...
- linux awk 教程,Linux awk使用案例教程
- 电脑看不到光驱盘符,应该如何解决
- 使用TestContainers提高测试性能
- 什么是千兆光纤收发器?其产品标准具体有哪些?
- Bootstrap学习笔记01
- 数组元素前移后移 RUNOOB python练习题 68
- lora网关软件设计_SX1301网关设计 LoRaWAN网关 评估开发套件sx1278双向测试云平台LPKT001...
- 脉位调制解调 matlab,基于matlab的am调制解调
- Ubuntu 20.04 安装 ModSecurity3.0+Nginx
- Julia : Array !, [1,2] !=[1 2]'
- markdown模板(个人使用)
- C/C++ 函数出入口
- 如何在 Windows 上查看 HEIC 格式照片
- 每日学口语(持续更新)
- 华为ensp Cloud连接使用及创建环回适配器网卡
- PowerBuilder 开发的游戏(扫雷)
- 赛门铁克警告Switch模拟器下载链接实为垃圾站点
热门文章
- android录音波浪动画_Android 自定义波浪动画--让进度浪起来~
- 使用click创建完美的Python命令行程序
- k线顶分型 python_顶底分型的实战操作要点(转)
- php 各种路由分析_thinkphp5路由详解
- RD650 raid5 linux,联想RD650服务器Raid5配置图文教程.docx
- 面向对象2(构造函数、实例对象、原型对象——关系理解)
- 【数据库】商品信息表的设计
- 美图公司2018年营收27.9亿元 同比下滑37.8%
- R沟通 | 如何在Typora中设置免费的图床
- 关于程序员背景做公众号的想法