在线抠图网站速抠图sukoutu.com全面技术解析之canvas应用
- 技术关键词
Canvas应用,泛洪算法(Flood Fill),图片缩放,相对位置等比缩放,判断一个点是否在一个平面闭合多边形,nginx代理
- 业务关键词
在线抠图,智能抠图,一键抠图,钢笔抠图,矩阵抠图,图片处理,图片压缩,图片尺寸,图片格式,图片透明度,图片下载
- 引用组件(前端)
Jquery,Canvas,Jcrop, Layer,MiniColors
- 技术解析背景
发表这篇随笔,一方面帮助前端的同学认识Canvas的实际应用场景和了解相关技术点,另一方面让sukoutu.com能够帮助更多的人去快速高效的完成抠图。
作为一名后端研发去开发一套纯前端的在线抠图工具实际上看起来有些疑惑和怪异,或许是因为 14年5月发表的一个随笔 html5 canvas+js实现ps钢笔抠图 的延续。
发表在知乎上的一篇文章 能让你知道sukoutu.com上线的原由、目的以及相关功能简介。

- 速抠图网站实现原理
网站几乎没有和后端服务做交互。后端用nginx作为server,另外代理了三方房展的图片访问(解决前端跨域访问网络图片跨域禁止canvas渲染的问题,通过nginx代理访问规避这个问题)。图片上传及图片操作等均在客户端浏览器上完成(图片操作流畅的很),因为有Canvas,所以整个工具网站的核心都在于js的交互及canvas的应用。
- 智能抠图(仿PS魔法棒效果)
这里参考了一些开源项目和泛洪算法(Flood Fill)的实现案例。对于一次纯色或者背景色差比较大的图片抠图,基本都能实现一键抠图的效果,通过点击滑选闭合色区来实现抠图,但是对于背景色差复杂的图片就很难实现自己想要的抠图了。
算法参考:图像分割经典算法--《泛洪算法》(Flood Fill)
实现原理:底层放图片,顶层放canvas,将图片按照对等尺寸渲染至到画布上得到ImageData,鼠标点击获取ImageData RGB 色值,用floodfill算法得到闭合外围坐标,在顶层canvas渲染边线(ctx.putImageData)
init: function (img) {
this.data.img = img;
this.data.tempCanvas = document.createElement('canvas');
var tempCtx = this.data.tempCanvas.getContext('2d');
//切记,原始图像大小
tempCtx.canvas.width = panel.data.targetImgWidth;
tempCtx.canvas.height = panel.data.targetImgHeight;
tempCtx.drawImage(img, 0, 0, panel.data.targetImgWidth, panel.data.targetImgHeight);
this.data.imgData = tempCtx.getImageData(0, 0, panel.data.targetImgWidth, panel.data.targetImgHeight);
},
- 钢笔抠图
钢笔抠图参考 html5 canvas+js实现ps钢笔抠图
实现原理:底层放图片,顶层放canvas,鼠标点击坐标存放到array中,canvas根据坐标list画线画点,canvas的 globalCompositeOperation = "destination-out" 属性可以实现通过由多个点构成的闭合区间设置成透明色穿透画布背景色或是背景图片。
- 矩阵抠图
这里用的是非常实用的Jcrop插件,参考Jcrop官网 ,提供了丰富的api,比如等比、移动等实用的功能。
- 图片等比缩放(很实用)
解决图片加载要等比缩放到画布中,并且居中显示。
function imgScale(src, w, h, fun) {
var img = new Image();
img.src = src;
img.onload = function () {
var wi = img.width;
var he = img.height;
var toHe = he * w / wi;
var toWi = 0;
if (toHe > h) {
toWi = wi * h / he;
toHe = h;
} else {
toWi = w;
}
fun(toWi, toHe);
};
}
- 相对位置等比缩放
在实现钢笔抠图或矩阵抠图需要放大,并且钢笔及矩阵坐标list也要等比缩放,需要用到如下算法来实现。
_scale = function (c, a, f) {
x1 *= c.x;
y1 *= c.y;
x2 *= c.x;
y2 *= c.y;
if (a) {
_values = [1.0000000000000002, -0, -0, 1.0000000000000002];
var b = transform(a.x - translationStart.x, a.y - translationStart.y);
var d = transform(c.x * -b.x, c.y * -b.y);
translation.x = d.x + a.x;
translation.y = d.y + a.y
}
};
transform = function (b, d, a) {//两中心x差,两中心y差
var c = new Point(_values[0] * b + _values[1] * d, _values[2] * b + _values[3] * d);
return c
};
- Canvas应用
图片压缩、图片尺寸调整、图片背景色、图片透明度实际均可通过canvas属性来操作
//透明度
ctx.globalAlpha = imgCreate.cutObj.alpha;
//背景色
ctx.fillStyle = imgCreate.cutObj.color;
//根据坐标list裁剪图片
var ctx = $("#createCanvas")[0].getContext('2d');
ctx.beginPath();
ctx.moveTo(0, 0);
for (var i = 0; i < proxy.cutObj.pointArray.length; i++) {
ctx.lineTo(proxy.cutObj.pointArray[i].pointx, proxy.cutObj.pointArray[i].pointy);
}
ctx.lineTo(proxy.cutObj.pointArray[0].pointx, proxy.cutObj.pointArray[0].pointy);
ctx.clip();
ctx.drawImage(proxy.cutObj.imgObj, tempPointArray[0].pointx * -1, tempPointArray[0].pointy * -1, proxy.cutObj.width, proxy.cutObj.height);
//生成及下载图片兼容(ie\谷歌\火狐)
var fileName = proxy.cutObj.name + "." + proxy.cutObj.suffix.replace("e", "");
if (window.navigator.msSaveOrOpenBlob) {
var imgData = $("#createCanvas")[0].msToBlob();
var blobObj = new Blob([imgData]);
window.navigator.msSaveOrOpenBlob(blobObj, fileName);
} else {
var imgData = $("#createCanvas")[0].toDataURL("image/" + imgCreate.cutObj.suffix, parseFloat(imgCreate.cutObj.quality));
imgData = imgData.replace("image/" + imgCreate.cutObj.suffix, 'image/octet-stream');
var a = document.createElement('a');
var event = new MouseEvent('click');
a.download = fileName;
a.href = URL.createObjectURL(dataURIToBlob(imgData));
a.dispatchEvent(event);
}
在线抠图网站速抠图sukoutu.com全面技术解析之canvas应用的更多相关文章
- html5 canvas+js实现ps钢笔抠图(速抠图 www.sukoutu.com)
html5 canvas+js实现ps钢笔抠图(速抠图 www.sukoutu.com) 根据html5 canvas+js实现ps钢笔抠图的实现,aiaito 开发者开发了一套在线抠图工具,速抠 ...
- 收集各种在线HTTP网站载入速度(响应时间)站长测试(检测)工具
收集各种在线HTTP网站载入速度(响应时间)站长测试(检测)工具 名称\详情 简单功能描述 推荐星级 演示/示例 监控宝 从中国多地对你提交的URL进行载入速度(响应时间)测试 ★★★★★ 17C ...
- IT在线学习网站总结
以下是我自己做软件过程中发现的一些不错的IT学习网站,个人感觉比较受用,故总结出来以供IT爱好者一起学习: www.maiziedu.com 麦子学院 www.jikexueyuan.com 极客学 ...
- 在线音乐网站【04】Part two 功能实现
上一篇博客里面已近总结了三个功能的具体实现,今天把剩余功能的具体实现补充总结,如果你想对整个小项目有清楚的了解,建议去看下前几篇博客. 1.在线音乐网站(1)需求和功能结构 2.在线音乐网站(2 ...
- 在线音乐网站【03】Part one 功能实现
今天打算把网站功能的具体实现给总结一下,如果你想了解整个小项目,建议你先看看前面2篇博客. 1.在线音乐网站(1)需求和功能结构 2.在线音乐网站(2)数据库和开发环境 7.网站主要模块实现 a.在线 ...
- 我是怎么开发一个小型java在线学习网站的
2016/1/27 11:55:14 我是怎么开发一个小型java在线学习网站的 一直想做一个自己的网站(非博客),但是又不知道做什么内容的好,又一次看到了w3schools,就萌发了开发一个在线ja ...
- HTML5初学者福利!11个在线学习网站推荐
HTML5初学者福利!11个在线学习网站推荐 HTML5的强大及流行趋势,让更多的人想要系统的对它进行学习.而大多数人获取HTML5知识的重要途径都是网络,不过面对五花八门的搜索结果,是不是觉得摸不着 ...
- 六:在线工具网站,让你PC上要装的软件少一半!
记住这几个在线工具网站,让你PC上要装的软件少一半! 一.uzer.me——丰富的云端应用聚合 这个云平台将我们常用的Office系列软件.Adobe家族的系列软件……乃至CAD制图都整合在了云端,随 ...
- 初学者福音——10个最佳APP开发入门在线学习网站
根据Payscale的调查显示,现在的APP开发人员的年薪达到:$66,851.这也是为什么那么多初学的开发都想跻身到APP开发这行业的主要原因之一.每当你打开App Store时候,看着琳琅满目的A ...
随机推荐
- 零基础学python-3.2 变量赋值
这一节我们来具体展开变量赋值 1.以下我们举各种赋值的样例 anInt=12 anFloat=2.2 anStr='string' aList=['a','a','a'] anArray=(1,2,3 ...
- Android Problem- android.content.res.Resources$NotFoundException: String resource ID #0xa
在使用listview时出现错误android.content.res.Resources$NotFoundException: String resource ID #0xa 经查证是在调用Text ...
- PHP生成excel(1)
先到PHPExcel官网下载PHPExcel类 http://phpexcel.codeplex.com/ 把excel类包含进来,然后直接使用 <?php require "./PH ...
- 一套扁平化界面风格的flex 皮肤
意外在git上发现这个项目.似乎刚開始不久.部分控件的新皮肤似乎还没完毕.只是个人感觉挺不错的.大家认为呢? =>git地址:https://github.com/akamud/FlatSpar ...
- Linux上Libevent的安装
1.下载wget -O libevent-2.0.21-stable.tar.gz https://github.com/downloads/libevent/libevent/libevent-2. ...
- IPv4与IPv6数据报格式
IPv4: IPv4数据报中的字段: 版本号:规定了数据报的IP协议版本,通过查看版本号,路由器能够确定如何解释IP数据报的剩余部分,因为不同IP版本使用不同的数据报格式. 首部长度:IPv4数据报可 ...
- 2016/06/13 phpexcel 未完待续
①准备工作: 1,php版本不能太低 2,去官网下载PHPExcel插件 http://phpexcel.codeplex.com/ 3,解压后提取classes文件夹到工作目录,并重命名为PH ...
- java随记2
1.Arrays java8里新添加了parallelSort等parallel开头的方法,表示利用cpu并行的能力 2.面向对象 如果继承树里的某个类要被初始化时,系统将会同时初始化该类的所有父类 ...
- awk基本语法
1 awk处理的对象 1.1 record awk处理时,默认会将文件按照换行符,分隔成record.默认分隔符是换行符. 1.2 filed 对于每个record,awk自动又分隔成filed.默认 ...
- 用 nodejs 写一个命令行工具 :创建 react 组件的命令行工具
用 nodejs 写一个命令行工具 :创建 react 组件的命令行工具 前言 上周,同事抱怨说 react 怎么不能像 angular 那样,使用命令行工具来生成一个组件.对呀,平时工作时,想要创建 ...