最近在研究html5 canvas的过程中,发现,canvas为前端对图像的处理开辟了一条新的道路,canvas可以做到很多事情,甚至可以做个类似于PhotoShop的东西,曾经本人在一家软件工作就做类似的工作,可以看一下我之前开发的软件:

这个就是canvas实现的类似于Adobe Photoshop,足以见得canvas的强大之处!

本文就是抽出其中一个小的功能点,来简单聊聊canvas强大之处:我们来一步步实现一个简单的智能抠图功能:(具体的代码见我的github:monkeyWangs/Matting)

1.环境准备

本人采用ES6语法作为开发环境,选用webpack作为构建工具,于是乎,我们有了webpack.config.js

/*** @author monkeyWang**//* 引入操作路径模块和webpack */
var path = require('path');
var webpack = require('webpack');module.exports = {/* 输入文件 */entry: './src/index.js',output: {/* 输出目录,没有则新建 */path: path.resolve(__dirname, './dist'),/* 静态目录,可以直接从这里取文件 */publicPath: '/dist/',/* 文件名 */filename: 'matting.js'},module: {rules: [/* 用babel来解析js文件并把es6的语法转换成浏览器认识的语法 */{test: /\.js$/,loader: 'babel-loader',/* 排除模块安装目录的文件 */exclude: /node_modules/}]}
}

这样变准备好了开发用的基本环境,接下来我们来实现具体的核心代码,为了方便起见,我的代码全写在了inde.js

2.代码实现

首选我们需要新建一个对象:

/*** @author monkeywang* Date: 17/3/30*/
class Matting {}

然后我们需要接受用户上传的图片文件:

class Matting {
/*** 构造函数* @param file*/constructor(file) {this.file = file}
}

再接着把图片文件转成base64格式,所以我们在类中建了一个createStream方法:

createStream() {
let reader = new FileReader()
let ext = this.file.name.substring(this.file.name.lastIndexOf(".") + 1).toLowerCase()
if (ext != 'png' && ext != 'jpg' && ext != 'jpeg') {
alert("图片的格式必须为png或者jpg或者jpeg格式!")
return}
reader.onload = (e) => {
let src = e.target.resultlet img = new Image()
img.src = srclet w = img.widthlet h = img.heightthis.fitch(w, h, img)}
reader.readAsDataURL(this.file)
}

然后,开始我们的抠图逻辑代码之前,先描述一下我的思想:颜色属性其实是由RGBA四个元素组成的,RGB,代表三基色,A代表透明度,当A的值为0,则表示这个颜色是纯透明的,所以我们的主要逻辑就是把背景色设置为透明就好了。

创建一个canvas画布,然后把图片放到这个画布中,接着取这个图片上下左右四个点的像素,接下来要扣除这个图片的背景,那么,就需要去对整个图片的像素点颜色和背景色之前的区别,如果颜色相同,则把这个颜色的透明度设置成0

fitch(width, height, img) {let dataUrllet c = document.createElement("canvas")c.width = widthc.height = heightlet ctx = c.getContext("2d")ctx.drawImage(img, 0, 0)/*** 取图片四个脚边的像素点rgba* @type {*}*/let tl = Array.prototype.slice.call(ctx.getImageData(0, 0, 1, 1).data).join(',')let tr = Array.prototype.slice.call(ctx.getImageData(width - 1, 0, 1, 1).data).join(',')let br = Array.prototype.slice.call(ctx.getImageData(width - 1, height - 1, 1, 1).data).join(',')let bl = Array.prototype.slice.call(ctx.getImageData(0, height - 1, 1, 1).data).join(',')let imgdata = [tl, tr, bl, br] // 四个取色点let selfImageData = [] // 当前rgbaimgdata.sort()// 目前只支持纯色背景抠图,简单的判断是否为纯色let deferNum = this.unique(imgdata).lengthif (deferNum <= 1) {{selfImageData = imgdata[1].split(",") // 设置要扣除的主题色let isPNG = true // 判断是否已经扣过let imgDataUrl = ctx.getImageData(0, 0, width, height) //获取像素点let data = imgDataUrl.datafor (let i = 0; i < data.length; i += 4) {// 得到 RGBA 通道的值let r = data[i]let g = data[i + 1]let b = data[i + 2]/*** function 判断颜色是不是属于背景色* @param numerical* @param index* @returns {boolean}*/let isIn = (numerical, index) => {if (selfImageData[3] == 0) {isPNG = falsereturn false}return numerical > parseInt(selfImageData[index]) && numerical < parseInt(selfImageData[index])// 去掉边缘色}if ([r, g, b].every(isIn)) {data[i + 3] = 0 // 设置背景透明}}// 将修改后的代码复制回画布中ctx.putImageData(imgDataUrl, 0, 0)dataUrl = c.toDataURL("image/png")if (isPNG) {/*** 创建下载链接 进行图片下载* @type {Element}*/let a = document.createElement('a')a.href = dataUrl //下载图片a.download = '未命名.png'a.click()}else {alert('背景已抠除!')}}}else {alert('只支持纯色背景抠图!')}}

然后我们测试一下效果:创建index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><input type="file" id="file"><button onclick="matting()">开始抠图</button>
</body>
<script src="./dist/matting.js"></script>
<script>function matting() {var file = document.getElementById('file').files[0];var mat = new Matting(file);mat.createStream();}
</script>
</html>

然后我们选择一个纯色背景图

抠图后,我们看看:

确实完成了抠图。

当然实现算法还不是很完善,主要是为了给大家展示canvas的无限可能,当然我也在逐步优化算法中,使得图片抠图更加完美,更加智能,也欢迎大家的star, pullrequest

canvas简单实现纯色背景图片抠图相关推荐

  1. java 生成纯色图片_canvas简单实现纯色背景图片抠图(示例代码)

    最近在研究html5 canvas的过程中,发现,canvas为前端对图像的处理开辟了一条新的道路,canvas可以做到很多事情,甚至可以做个类似于PhotoShop的东西,曾经本人在一家软件工作就做 ...

  2. 【ps功能精通】4.简单背景图片抠图

    [ps功能精通]4.简单背景图片抠图 学习目标: 学习内容: 学习时间: 学习产出: 一.套索工具组(L) 二.魔棒工具(W) 三.橡皮擦工具组 四.色彩范围: 学习目标: 简单背景图片抠图 学习内容 ...

  3. java编写的网页版 纯色背景图片去除底色工具,变成透明背景的图片工具发布...

    程序使用java语言编写,工作原理是取图片边缘的像素点作为要替换的背景色,然后将所有像素点与该颜色进行比较,发现相同则将颜色不透明度设置为0,使颜色完全透明. 下面是一个在线版: 一.访问图片去底工具 ...

  4. 纯色背景图片去除底色工具发布,将背景变透明

    一.访问图片去底工具BgRemover在线版 ,点击"浏览"按钮. 二.选择需要去底的图片. 三.BgRemover工具会自动将"纯色背景图片"处理为" ...

  5. JAVA编写的纯色背景图片去除底色变成透明背景图片的工具

    程序使用java语言编写,工作原理是取图片边缘的像素点作为要替换的背景色,然后将所有像素点与该颜色进行比较,发现相同则将颜色不透明度设置为0,使颜色完全透明. 在线示例: 一.访问图片去底工具BgRe ...

  6. Android 更改纯色背景图片颜色,可实现一张背景圆形图片展示不同颜色

    Android 更改纯色背景图片颜色,可实现一张背景圆形图片展示不同颜色 项目中可能会遇到比如多个纯色圆形背景列表或者说纯色圆形头像背景,一般让UI设计师设计多张背景图:但是有更好的方法只需一张图就可 ...

  7. idea修改背景为护眼背景模式、淡黄色、淡绿色等,内附多张纯色背景图片供使用

    文章目录 前言 一.更换背景的步骤 1.1File--Setting 1.2Appearance&Behavior--Appearance--Background lmage... 1.3选择 ...

  8. android 图片转换圆形 黑色背景,Android 更改纯色背景图片颜色,可实现一张背景圆形图片展示不同颜色...

    Android 更改纯色背景图片颜色,可实现一张背景圆形图片展示不同颜色 项目中可能会遇到比如多个纯色圆形背景列表或者说纯色圆形头像背景,一般让UI设计师设计多张背景图:但是有更好的方法只需一张图就可 ...

  9. 为canvas画布动态设置背景图片

    为canvas画布动态设置背景图片 关键是将canvas和img标签放到同一个盒子里,盒子设置相对位置,并且canvas和img需要设置相同的相对位置 <div class="list ...

最新文章

  1. 谷歌发布颠覆性研究:不训练不调参,AI自动构建超强网络,告别炼丹一大步...
  2. 如何配置MySQL?(三)
  3. The server time zone value is unrecognized or repr
  4. bootstrap42-Bootstrap 按钮组
  5. [笔记]路由器与交换机的区别
  6. [Java基础]Calendar类基础
  7. OOB与COM交互读写本地文件
  8. BootstrapTable组件冻结列
  9. 存储过程之游标笔记小结
  10. 剑指offer (01):赋值运算符函数 (C++ 实现)
  11. spring Bean的初始化和销毁 (使用注解)
  12. CentOS 7.X配置连接网络
  13. 计算机基础知识上机操作excer,excel上机操作题及答案
  14. 五、Python复习教程(重点)-爬虫框架实战
  15. 教你用Python自制一张好看的指数估值图!这招很好用!
  16. MATLAB中对于矩阵的算术运算、关系运算、逻辑运算、转置、求逆、求和和求积
  17. 【转】乔布斯演讲黄金法则
  18. Visual Paradigm简单教程(2):绘制序列图
  19. 永辉私域流量模式案例:如何利用商域流量打造好企业自己的私域流量池?
  20. python3编写人工智能_人工智能学习第三章 编写第一个Python程序 及概念

热门文章

  1. 计算机未来的发展250字,电脑迷250字作文
  2. 【MATLAB项目实战】基于RGB特征的火焰检测
  3. 服务器文件怎么删,怎么删除服务器文件
  4. JAVA多媒体网络教学计算机毕业设计Mybatis+系统+数据库+调试部署
  5. @refreshscope注解
  6. aimp输出dsd_极客评论:音乐播放器AIMP 2
  7. iOS MultipeerConnectivity
  8. Android 9 wifi PNO 扫描
  9. 码垛机器人模型图纸分享(附下载)
  10. 台式计算机硬盘能扩大吗,电脑怎么增加磁盘内存