思路:先打开相册,选取图片,在剪切图片,转化为base64格式,然后上传到七牛存储,返回url,再传给后端,整个流程就是这样。用的是angular框架,图像插件用到imagecropper.js,废话不多说,直接上代码。

效果:

用到的插件

<!DOCTYPE html>
<html lang="en" ng-app="">
<head>
<meta name="viewport"
content="initial-scale=1,maximum-scale=1,user-scalable=no,width=device-width,height=device-height"/>
<meta charset="UTF-8">
<title></title> <script type="text/javascript" src="app/lib/jquery.js"></script> <script type="text/javascript" src="app/lib/ionic/js/ionic.bundle.min.js"></script> <!-- 上传头像插件 --> <script src="app/lib/headimg/imagecropper.js"></script> <base href='/'/> </head>
<body>
<ion-nav-view>
</ion-nav-view> <script type="text/javascript" src="app/dist/js/main-396e1d7cdb.js"></script> </body>
</html>

 

页面

<ion-header-bar align-title="center" class="bar-light">
<button ui-sref="home.my" class="button button-clear"><i class="icon ion-ios-arrow-left"></i></button>
<h1 class="title">个人资料</h1>
</ion-header-bar>
<ion-content class="my">
<ion-list>
<ion-item class="item-input" style="height:1.1rem;" >
<form id="form0" class="item-icon-right" href="javascript:void(0);" style="width: 100%">
<span class="input-label f26" style="margin-top:0.4rem; ">头像</span>
<i class="icon "><img ng-src="{{info.headimgurl||'app/dist/img/my/me_img.png'}}" style="width: 0.8rem;position: absolute;top: 0.1rem;right:0.7rem;border-radius:50%;border:3px solid rgba(0,0,0,0.3)" /></i>
<!-- <form name="form0" id="form0" style="width: 100%"> -->
<input type="file" name="file0" id="file0" multiple="multiple"><br>
<!-- </form> -->
<i class="icon "><img src="app/dist/img/my/arrow_icon.png" class="arrow_icon"></i>
</form>
</ion-item> </ion-list> </ion-content>
<div class="img-container">
<img id="img0" src="">
<div class="close"><button class="button button-large button-light">取消</button></div>
<div class="saveBtn" on-tap="save()"><button class="button button-large button-light" >选取</button></div>
</div>
<img class="newImg" src="">

css

.albumsbox {
width: 18.9375rem;
position: absolute;
bottom:;
left: 0.53125rem;
display: none;
z-index:; }
.albumsbox .albums, .albumsbox .cancel {
width: 100%;
height: 6.1875rem;
background: #fff;
border-radius: 0.625rem;
color: #333333;
font-size: 0.8125rem;
line-height: 3.0625rem;
text-align: center; }
.albumsbox .albums .line, .albumsbox .cancel .line {
border-bottom: 1px solid #d1d1d4; }
.albumsbox .cancel {
height: 3.0625rem;
margin: 0.34375rem 0rem 0.5625rem 0rem; } .container {
position: absolute;
top:;
left:;
width: 100%;
height: 100%;
display: none;
background: #000; }
.container #wrapper {
width: 100%;
height: 12.5rem;
position: absolute;
top: 40%;
margin-top: -6.25rem;
left:; }
.container #wrapper #cropper {
width: 100%; }
.container #wrapper #previewContainer {
display: none; } /*img prev*/
.img-container {
width: 100%;
height: 100%;
position: absolute;
top:;
left:;
display: none;
background: #000; } .newImg {
display: none; } .close {
height: 1.1875rem;
width: 30%;
text-align: center;
color: #fff;
font-size: 0.8125rem;
line-height: 1.1875rem;
position: absolute;
bottom: 1.5625rem;
left:; } .saveBtn {
height: 1.1875rem;
width: 30%;
text-align: center;
color: #fff;
font-size: 0.8125rem;
line-height: 1.1875rem;
position: absolute;
bottom: 1.5625rem;
right:; } .cropper-container {
font-size:;
line-height:;
position: relative;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
direction: ltr !important;
-ms-touch-action: none;
touch-action: none;
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none; } .cropper-container img {
display: block;
width: 100%;
min-width: 0 !important;
max-width: none !important;
height: 100%;
min-height: 0 !important;
max-height: none !important;
image-orientation: 0deg !important; } .cropper-wrap-box,
.cropper-canvas,
.cropper-drag-box,
.cropper-crop-box,
.cropper-modal {
position: absolute;
top:;
right:;
bottom:;
left:; } .cropper-wrap-box {
overflow: hidden; } .cropper-drag-box {
opacity:;
background-color: #fff;
filter: alpha(opacity=0); } .cropper-modal {
opacity: .5;
background-color: #000;
filter: alpha(opacity=50); } .cropper-view-box {
display: block;
overflow: hidden;
width: 100%;
height: 100%;
outline: 1px solid #39f;
outline-color: rgba(51, 153, 255, 0.75); } .cropper-dashed {
position: absolute;
display: block;
opacity: .5;
border: 0 dashed #eee;
filter: alpha(opacity=50); } .cropper-dashed.dashed-h {
top: 33.33333%;
left:;
width: 100%;
height: 33.33333%;
border-top-width: 1px;
border-bottom-width: 1px; } .cropper-dashed.dashed-v {
top:;
left: 33.33333%;
width: 33.33333%;
height: 100%;
border-right-width: 1px;
border-left-width: 1px; } .cropper-center {
position: absolute;
top: 50%;
left: 50%;
display: block;
width:;
height:;
opacity: .75;
filter: alpha(opacity=75); } .cropper-center:before,
.cropper-center:after {
position: absolute;
display: block;
content: ' ';
background-color: #eee; } .cropper-center:before {
top:;
left: -3px;
width: 7px;
height: 1px; } .cropper-center:after {
top: -3px;
left:;
width: 1px;
height: 7px; } .cropper-face,
.cropper-line,
.cropper-point {
position: absolute;
display: block;
width: 100%;
height: 100%;
opacity: .1;
filter: alpha(opacity=10); } .cropper-face {
top:;
left:;
background-color: #fff; } .cropper-line {
background-color: #39f; } .cropper-line.line-e {
top:;
right: -3px;
width: 5px;
cursor: e-resize; } .cropper-line.line-n {
top: -3px;
left:;
height: 5px;
cursor: n-resize; } .cropper-line.line-w {
top:;
left: -3px;
width: 5px;
cursor: w-resize; } .cropper-line.line-s {
bottom: -3px;
left:;
height: 5px;
cursor: s-resize; } .cropper-point {
width: 5px;
height: 5px;
opacity: .75;
background-color: #39f;
filter: alpha(opacity=75); } .cropper-point.point-e {
top: 50%;
right: -3px;
margin-top: -3px;
cursor: e-resize; } .cropper-point.point-n {
top: -3px;
left: 50%;
margin-left: -3px;
cursor: n-resize; } .cropper-point.point-w {
top: 50%;
left: -3px;
margin-top: -3px;
cursor: w-resize; } .cropper-point.point-s {
bottom: -3px;
left: 50%;
margin-left: -3px;
cursor: s-resize; } .cropper-point.point-ne {
top: -3px;
right: -3px;
cursor: ne-resize; } .cropper-point.point-nw {
top: -3px;
left: -3px;
cursor: nw-resize; } .cropper-point.point-sw {
bottom: -3px;
left: -3px;
cursor: sw-resize; } .cropper-point.point-se {
right: -3px;
bottom: -3px;
width: 20px;
height: 20px;
cursor: se-resize;
opacity:;
filter: alpha(opacity=100); } .cropper-point.point-se:before {
position: absolute;
right: -50%;
bottom: -50%;
display: block;
width: 200%;
height: 200%;
content: ' ';
opacity:;
background-color: #39f;
filter: alpha(opacity=0); } @media (min-width: 768px) {
.cropper-point.point-se {
width: 15px;
height: 15px; } }
@media (min-width: 992px) {
.cropper-point.point-se {
width: 10px;
height: 10px; } }
@media (min-width: 1200px) {
.cropper-point.point-se {
width: 5px;
height: 5px;
opacity: .75;
filter: alpha(opacity=75); } }
.cropper-invisible {
opacity:;
filter: alpha(opacity=0); } .cropper-hide {
position: absolute;
display: block;
width:;
height:; } .cropper-hidden {
display: none !important; } .cropper-move {
cursor: move; }

js

/**
* laoyou Module
*
* Description
*/
angular.module('app').controller('myEditCtrl', ['$scope', 'api', '$rootScope', '$http', '$state', '$stateParams','$ionicModal','qiniuConfig', function($scope, api, $rootScope, $http, $state, $stateParams,$ionicModal,qiniuConfig) {
var showLoad = $rootScope.showLoad; $http.post("member/info",{test:1}).success(function(data){
$scope.info=data.data;
if(!$scope.info.birthday){
$scope.info.birthday=new Date("1951-01-01");
}else{
$scope.info.birthday=new Date($scope.info.birthday);
}
}).error(function(){
$rootScope.loadFn.hide();
}); var config=angular.copy(qiniuConfig);
// console.log(config)
if(config){
var token=config.UpToken;
} /*picBase是base64图片带头部的完整编码*/
function putb64(picBase){ /*picUrl用来存储返回来的url*/
var picUrl; /*把头部的data:image/png;base64,去掉。(注意:base64后面的逗号也去掉)*/
picBase=picBase.substring(22); /*通过base64编码字符流计算文件流大小函数*/
function fileSize(str)
{
var fileSize;
if(str.indexOf('=')>0)
{
var indexOf=str.indexOf('=');
str=str.substring(0,indexOf);//把末尾的’=‘号去掉
} fileSize=parseInt(str.length-(str.length/8)*2);
return fileSize;
} /*把字符串转换成json*/
function strToJson(str)
{
var json = eval('(' + str + ')');
return json;
} var url = "http://up.qiniu.com/putb64/"+fileSize(picBase);
var xhr = new XMLHttpRequest();
xhr.onreadystatechange=function()
{
if (xhr.readyState==4){
var keyText=xhr.responseText;
// alert(keyText)
/*返回的key是字符串,需要装换成json*/
keyText=strToJson(keyText); /* http://ojvh6i96g.bkt.clouddn.com/是我的七牛云空间网址,keyText.key 是返回的图片文件名*/
picUrl=config.recordPath+'/'+keyText.key;
// alert(picUrl);
$http.post("member/updateHead",{headimgurl:picUrl}).success(function (res) {
if( res.statusCode == 0) { window.location.reload();
}else{
alert("修改失败");
}
}).error(function(data){
alert("网络异常")
});
}
}
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/octet-stream");
xhr.setRequestHeader("Authorization", "UpToken "+ token); //token换成自己申请七牛的。
xhr.send(picBase); }
// var _czc = []; $("#file0").change(function(){
// _czc.push(["_trackEvent", "个人资料页","头像",""]);
// console.log($("#img0"))
var objUrl = getObjectURL(this.files[0]) ;
console.log("objUrl = "+objUrl) ;
if (objUrl) {
$("#img0").attr("src", objUrl) ;
$('.cropper-canvas img').attr('src',objUrl);
$('.cropper-view-box img').attr('src',objUrl);
}
var File=$('#img0').attr('src');
if(File!=''||File==undefined){
// $scope.openModal();
$(".my").css('opacity','0');
$('.img-container').show();
}
}) ; //建立一個可存取到該file的url
function getObjectURL(file) {
console.log(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 ;
} $('.close').click(function(){
$(".my").css('opacity','1');
$('.img-container').hide();
}) function convertToData(url, canvasdata, cropdata, callback) {
var cropw = cropdata.width; // 剪切的宽
var croph = cropdata.height; // 剪切的宽
var imgw = canvasdata.width; // 图片缩放或则放大后的高
var imgh = canvasdata.height; // 图片缩放或则放大后的高 var poleft = canvasdata.left - cropdata.left; // canvas定位图片的左边位置
var potop = canvasdata.top - cropdata.top; // canvas定位图片的上边位置 var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d'); canvas.width = cropw;
canvas.height = croph; var img = new Image();
img.src = url; img.onload = function() {
this.width = imgw;
this.height = imgh;
// 这里主要是懂得canvas与图片的裁剪之间的关系位置
ctx.drawImage(this, poleft, potop, this.width, this.height);
var base64 = canvas.toDataURL('image/jpg', 1); // 这里的“1”是指的是处理图片的清晰度(0-1)之间,当然越小图片越模糊,处理后的图片大小也就越小
callback && callback(base64) // 回调base64字符串
}
} $(function(){ var $image = $('.img-container > img'); $image.on("load", function() { // 等待图片加载成功后,才进行图片的裁剪功能
$image.cropper({
aspectRatio: 1 / 1   // 1:1的比例进行裁剪,可以是任意比例,自己调整
});
}) // 点击保存
// $(".saveBtn").on("click", function() {
$scope.save = function(){ var src = $image.eq(0).attr("src");
var canvasdata = $image.cropper("getCanvasData");
var cropBoxData = $image.cropper('getCropBoxData');
convertToData(src, canvasdata, cropBoxData, function(basechar) {
// 回调后的函数处理
$(".newImg").attr("src", basechar);
// alert(basechar)
putb64(basechar); });
}
}) }]);

其中qiniuConfig是自己向后台要的,这是上传图片的身份凭证,这是我的qiniuConfig。

这是我头像上传页面的路由。

如有什么问题,欢迎指正。

html5,js插件实现手机端实现头像剪切上传的更多相关文章

  1. HTML5——摒弃插件和前端框架的异步文件上传

    之前我从来没有体会到HTML5的便利,直到这次需要一个异步上传的功能功能.一开始我以为文件的一些声明必须为HTML5才管用,后来才知道添加了很多以前没有的标签,并可以直接播放视频,音频等.可以不再使用 ...

  2. 第三百九十节,Django+Xadmin打造上线标准的在线教育平台—Django+cropper插件头像裁剪上传

    第三百九十节,Django+Xadmin打造上线标准的在线教育平台—Django+cropper插件头像裁剪上传 实现原理 前台用cropper插件,将用户上传头像时裁剪图片的坐标和图片,传到逻辑处理 ...

  3. 头像截图上传三种方式之一(一个简单易用的flash插件)(asp.net版本)

    flash中有版权声明,不适合商业开发.这是官网地址:http://www.hdfu.net/ 本文参考了http://blog.csdn.net/yafei450225664/article/det ...

  4. 第三百九十六节,Django+Xadmin打造上线标准的在线教育平台—其他插件使用说,自定义列表页上传插件

    第三百九十六节,Django+Xadmin打造上线标准的在线教育平台—其他插件使用说,自定义列表页上传插件 设置后台列表页面字段统计 在当前APP里的adminx.py文件里的数据表管理器里设置 ag ...

  5. HTML5+Canvas+jQuery调用手机拍照功能实现图片上传(二)

    上一篇仅仅讲到前台操作,这篇专门涉及到Java后台处理.前台通过Ajax提交将Base64编码过的图片数据信息传到Java后台,然后Java这边进行接收处理.通过对图片数据信息进行Base64解码,之 ...

  6. springMVC 头像裁剪上传并等比压

    第一次写头像裁剪上传,原本想着直接本地预览裁剪再上传,可是时间有限,jquery.jcrop貌似并没有对 假设是ie下图片预览效果是滤镜做的  做出对应处理,也没有时间去改;仅仅好将就一下先把图片上传 ...

  7. jquery插件课程2 放大镜、多文件上传和在线编辑器插件如何使用

    jquery插件课程2 放大镜.多文件上传和在线编辑器插件如何使用 一.总结 一句话总结:插件使用真的还是比较简单的,引包,初始化,配置参数(json),配置数据(json),而后两步不是必须的.而且 ...

  8. egg.js 通过 form 和 ajax 两种方式上传文件并自定义目录和文件名

    egg.js 通过 form 和 ajax 两种方式上传文件并自定义目录和文件名 评论:10 · 阅读:8437· 喜欢:0 一.需求 二.CSRF 校验 三.通过 form 表单上传文件 四.通过 ...

  9. 5.21学习总结——android开发实现用户头像的上传

    最近在做个人头像的上传,具体是能调用摄像头和从相册进行选择.本篇文章参考的我的同学的博客,大家有兴趣可以去原作者那里去看看: Hi(.・∀・)ノ (cnblogs.com) 1.使用glide进行图片 ...

随机推荐

  1. 使用git把项目提交到github

    1.需要在https://github.com/注册一个账户 2.注册成功后,新建一个repository,用来存放你要上传的项目,如下图所示 这里你需要输入你的项目的名称,可以对你的项目进行描述,如 ...

  2. DbEntry在Vs2012里的配置

    dbentry官方的版本还不支持vs2012,要再vs2012中使用,必须做下调整 1:新建类库项目,然后添加dbentry 的dll引用. 2:在建好的类库项目中.csproj 新添加了类库项目后, ...

  3. Linux_linux中profile、bashrc、bash_profile之间的区别和联系(转)

    /etc/profile:此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行. 并从/etc/profile.d目录的配置文件中搜集shell的设置. 英文描述为: # /etc/p ...

  4. 实现viewpager下的圆点滑动

    在Drawable目录下创建资源文件 使用shape标签画出背景圆点与当前圆点 背景圆点: <?xml version="1.0" encoding="utf-8& ...

  5. JAVA_JSON

    package cn.kjxy.JSON; import org.json.JSONArray; import org.json.JSONException; import org.json.JSON ...

  6. centos6 安装python2.7+和神器pip

    centos自带python版本是2.6.6,需要采用编译安装的方法安装py27 1.提前yum安装python以及pip神器依赖包(有没有必要都装上就是了,早晚有用): yum install -y ...

  7. 根据class显示或隐藏多个div

    引用一下jquery,然后function放head中 function test(){ $(".1").css("display","none&qu ...

  8. 7.2 GRASP原则二:信息专家 Information Expert

    2.GRASP原则二:信息专家 Information Expert  What is a general principle of assigning responsibility to obje ...

  9. class_create(),device_create自动创建设备文件结点【转】

    本文参考来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhenwenxian/archive/2010/03/28/5424434.aspx 本文转自:http://ww ...

  10. JConsole连接远程linux服务器配置

    1.在远程机的tomcat的catalina.sh中加入配置 (catalina.sh路径在tomcat/bin下面 如/usr/local/tomcat/bin) if [ "$1&quo ...