在线抠图网站速抠图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 ...
随机推荐
- Mysql学习记录点
order by 数字,表示按照第几列来排序,可以从1开始,不能是0,也不能超过列数.
- c++中c_str()函数
https://zhidao.baidu.com/question/104592558.html
- ios9定位服务的app进入后台三分钟收不到经纬度,应用被挂起问题及解决方式
原来定位服务是10分钟收不到定位信息就挂起定位,如今变为最短3分钟,预计都是为了省电吧. 仅仅要你开启应用的后台定位,而且10分钟有一次定位,那么苹果就不会关闭你的线程.如今变成3分钟.若你的应用开启 ...
- DesiredSize,RenderSize&& Width ,ActualWidth
做UI的时候刚入门,很多属性摸不着头脑,需要的功能和属性不能很快联系联想到,所以要慢慢积累UIElement 的DesiredSize 和 RenderSize UIElement 的DesiredS ...
- TinyXML学习:TiXmlBase类
TiXmlBase: 作为整个TinyXML模型的基类,除了可以提供一些实用功能外,它几乎没有什么作用 TiXmlBase的友元类: friend class TiXmlNode; friend cl ...
- LZMA C# SDK 结合 UPK 打包压缩 多目录 Unity3d实例
上篇 LZMA C# SDK 子线程压缩与解压缩 Unity3d实例 讲了怎样使用 LZMA C# SDK 来对文件进行压缩与解压,当中提到 对于多目录能够先打包成 UPK 然后再 LZMA 压缩 ...
- openwrt: firstboot
# cat /sbin/firstboot #!/bin/sh /sbin/jffs2reset jffs2reset 是fstools里的工具.做的工作有: 在/proc/mtd里找到名为" ...
- Python调用C/Fortran混合的动态链接库--中篇
接下来,介绍一个简单的例子,从fortran中传递并返回一维自定义结构体数组到python注意点:1.fortran新标准支持可分配数组作为变量传入并在subroutine或function分配后返回 ...
- 完美解决android显示gif
今天是周5啊.纠结了一天.android显示gif,没该控件 网上找开源项目 找到个viewgif.该作者在各大站点都在推荐自己的项目...好吧.用下吧. . . . 结果呢: 图片略微一大就 内存溢 ...
- Apach Web Server区别于其他应用服务器的主要特点是什么?
Web服务器一般指的是处理静态请求或转发http请求的服务器,而应用服务器一般是用来处理动态请求的服务器.