下面就讲解一下,移动端上传照片,旋转,抠图,以及图片美白效果原理。
一、上传照片
下面是两种上传照片的方法
1、此方法被废弃,希望能给大家一点提示,和思考的空间
a、通过改变file的值获取图片路径,并把路径添加到img元素中,在页面中展示
b、图片上传,可以用form表单上传,但是获取不到返回值,可以用ajaxfileupload.js上传
<img id="pic" src="image/index3_photo.png" class="index3_photo" width="167" height="218">
<input id="upload" name="upload" accept="image/*" type="file" style="display: none"/>
<script>
$("#pic").click(function () {
$("#upload").click(); //隐藏了input:file样式后,点击头像就可以本地上传
$("#upload").on("change",function(){
var objUrl = getObjectURL(this.files[0]) ; //获取图片的路径,该路径不是图片在本地的路径
if (objUrl) {
var img=new Image()
img.src=objUrl
img.onload= function () {
$("#pic").attr({
"src":objUrl,
}) ; //将图片路径存入src中,显示出图片
}
}
});
});
//建立一個可存取到該file的url
function getObjectURL(file) {
var url = null ;
if (window.createObjectURL!=undefined) { // basic
url = window.createObjectURL(file) ;
} else if (window.URL!=undefined) { // mozilla(firefox)
url = window.URL.createObjectURL(file) ;
} else if (window.webkitURL!=undefined) { // webkit or chrome
url = window.webkitURL.createObjectURL(file) ;
}
return url ;
}
$.ajaxFileUpload({
url: '/file.php', //用于文件上传的服务器端请求地址
secureuri: false, //是否需要安全协议,一般设置为false
fileElementId: 'upload', //文件上传域的ID
dataType : 'content', //返回值类型 一般设置为json
success: function (data) //服务器成功响应处理函数
{
var data = eval('('+data+')')
},
error: function (data, status, e)//服务器响应失败处理函数
{
alert(e);
}
})
</script>
2、通过canvas画布上传照片,此方法被推荐
a、照片展示,通过file获取图片路径,画到canvas上,在用base64转化一下
b、上传图片,通过ajax post上传
<input type="file" id="upload">
<canvas id="canvas"></canvas>
<script src="jquery-2.2.1.min.js"></script>
<script>
$("#upload").bind("change", function () {
var file=document.getElementById("upload").files[0]
var URL=window.URL||window.webkitURL;
var blob=URL.createObjectURL(file)
var img=new Image()
img.src=blob
img.onload= function () {
drawCanvas(img)
}
})
var base64
function drawCanvas(img,i){
var canvas=document.createElement("canvas")
var ctx=canvas.getContext("2d"),imgW=img.width,imgH=img.height,resultW,resultH
resultW=imgW>640?640:imgW;
resultH=imgH/imgW*resultW
canvas.width=resultW
canvas.height=resultH
$("body").append(canvas)
ctx.drawImage(img,0,0,resultW,resultH)
base64 = canvas.toDataURL("image/jpeg")
}
$.post("url",{base64:base64}, function (data) {
},"json")
</script>
总结:之所以先第二种方案,因为第一种方法,直接上传最原始图片,图片尺寸大小都会影响服务器的速度,而且图片太大会导致上传失败,而用canvas先缩放图片尺寸大小,可以很好的完成上传
二、旋转图片
在上传过程中,如果不对图片进行处理,会因为拍摄角度,图片展示效果不会达到预期效果,而且不会进行五官识别
此方法主要借助exif.js获取照片拍摄角度进行旋转
checkImgAngel=function(n,m,h){
EXIF.getData(n, function () {
EXIF.getAllTags(n);
var imgOrient= EXIF.getTag(n, 'Orientation');
switch(imgOrient){
case 6://需要顺时针(向左)90度旋转
rotateImg(n,'left');
break;
case 8://需要逆时针(向右)90度旋转
rotateImg(n,'right');
break;
case 3://需要180度旋转
rotateImg(n,'right');//转两次
rotateImg(n,'right');
break;
}
})
}
function rotateImg(img, direction) {
var canvas = document.createElement("canvas")
var ctx = canvas.getContext("2d")
$(document.body).append(canvas)
var min_step = 0;
var max_step = 3;
if (img == null)return;
var height = img.height;
var width = img.width;
var step = 2;
if (step == null) {
step = min_step;
}
if (direction == 'right') {
step++;
step > max_step && (step = min_step);
} else {
step--;
step < min_step && (step = max_step);
}
//旋转角度以弧度值为参数
var degree = step * 90 * Math.PI / 180;
var ctx = canvas.getContext('2d');
switch (step) {
case 0:
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0);
break;
case 1:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, 0, -height);
break;
case 2:
canvas.width = width;
canvas.height = height;
ctx.rotate(degree);
ctx.drawImage(img, -width, -height);
break;
case 3:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, -width, 0);
break;
}
}
三、人脸抠图
此效果需要借助腾讯优图API完成,腾讯优图会提供人脸五官坐标,通过canvas的clip()方法,对人脸进行抠图
function drawLine(data,status){
var data = setData1(data,status)//接口返回数据并处理
ctx.save();
var len=data.length
ctx.beginPath();
ctx.moveTo(data[0].x,data[0].y)
for(var i=1;i<len;i++){
ctx.lineTo(data[i].x,data[i].y)
}
ctx.closePath();
ctx.clip();
ctx.drawImage(img, 0, 0);
ctx.restore()
}
注意:因为返回的坐标并不全是五官的轮廓坐标,所以需要开发人员先对数据进行处理,剔除不需要的坐标
四、人脸美白
主要原理是canvas的getImageData方法,获取到每一个像素点的rgba值,进行运算,在通过putImageData方法,重新渲染图片,先通过isPointInPath方法,把需要美白的部分点push到一个数组中
对脸部点进行处理,push到imgDataArr数组中
var imgDataArr=[]
function drawLine(data,status){
var data = setData1(data,status)//接口返回数据并处理
var len=data.length
ctx.beginPath();
ctx.moveTo(data[0].x,data[0].y)
for(var i=1;i<len;i++){
ctx.lineTo(data[i].x,data[i].y)
}
ctx.closePath();
ctx.restore()
getData()
}
function getData(){
var w = canvas.width
var h = canvas.height;
var resultw;
var resulth
for(var i=0;i<w;i++){
for(var j=0;j<h;j++){
resultw=j
resulth=i
if(ctx.isPointInPath(resultw,resulth)){
imgDataArr.push(i*w+j)
}
}
}
}
通过接口返回的脸部五官数据获取像素点,通过drawLine()在canvas上画出脸部模型,在通过isPointInPath方法,收集脸部数据
美白效果
function setImagedata(){
var imgData = ctx.getImageData(0,0,canvas.width,canvas.height)
for(var i= 0 ;i<imgDataArr.length;i++){
imgData.data[imgDataArr[i]*4+0]=imgData.data[imgDataArr[i]*4+0]+50
imgData.data[imgDataArr[i]*4+1]=imgData.data[imgDataArr[i]*4+1]+50
imgData.data[imgDataArr[i]*4+2]=imgData.data[imgDataArr[i]*4+2]+50
imgData.data[imgDataArr[i]*4+3]=255
}
ctx.putImageData(imgData,0,0);
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。