这里需要用到jquery Jcrop 插件实现前端选择图片区域效果
然后使用canvas裁剪图片,并把base64位的toDataURL图片转换成blob
最后使用XMLHttpRequest上传到服务器。
预览效果:
整体代码:
<!doctype html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"/> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/> <meta name="description" id="description1" content="1"> <meta name="renderer" content="webkit"> <meta name="format-detection" content="telephone=no"> <title>图片上传</title> <style type="text/css"> * { box-sizing: border-box; /* h5 */ -moz-box-sizing: border-box; /* Firefox */ -webkit-box-sizing: border-box; /* Safari */ margin: 0; padding: 0; outline: 0 none; font-weight: inherit; font-style: inherit; font-family: inherit; vertical-align: baseline; } .jcrop-holder { direction: ltr; text-align: center; margin: 0 auto; /* IE10 touch compatibility */ -ms-touch-action: none; } /* Selection Border */ .jcrop-vline, .jcrop-hline { background: #ffffff url("Jcrop.gif"); font-size: 0; position: absolute; } .jcrop-vline { height: 100%; width: 1px !important; } .jcrop-vline.right { right: 0; } .jcrop-hline { height: 1px !important; width: 100%; } .jcrop-hline.bottom { bottom: 0; } /* Invisible click targets */ .jcrop-tracker { height: 100%; width: 100%; /* "turn off" link highlight */ -webkit-tap-highlight-color: transparent; /* disable callout, image save panel */ -webkit-touch-callout: none; /* disable cut copy paste */ -webkit-user-select: none; } /* Selection Handles */ .jcrop-handle { background-color: #333333; border: 1px #eeeeee solid; width: 7px; height: 7px; font-size: 1px; } .jcrop-handle.ord-n { left: 50%; margin-left: -4px; margin-top: -4px; top: 0; } .jcrop-handle.ord-s { bottom: 0; left: 50%; margin-bottom: -4px; margin-left: -4px; } .jcrop-handle.ord-e { margin-right: -4px; margin-top: -4px; right: 0; top: 50%; } .jcrop-handle.ord-w { left: 0; margin-left: -4px; margin-top: -4px; top: 50%; } .jcrop-handle.ord-nw { left: 0; margin-left: -4px; margin-top: -4px; top: 0; } .jcrop-handle.ord-ne { margin-right: -4px; margin-top: -4px; right: 0; top: 0; } .jcrop-handle.ord-se { bottom: 0; margin-bottom: -4px; margin-right: -4px; right: 0; } .jcrop-handle.ord-sw { bottom: 0; left: 0; margin-bottom: -4px; margin-left: -4px; } /* Dragbars */ .jcrop-dragbar.ord-n, .jcrop-dragbar.ord-s { height: 7px; width: 100%; } .jcrop-dragbar.ord-e, .jcrop-dragbar.ord-w { height: 100%; width: 7px; } .jcrop-dragbar.ord-n { margin-top: -4px; } .jcrop-dragbar.ord-s { bottom: 0; margin-bottom: -4px; } .jcrop-dragbar.ord-e { margin-right: -4px; right: 0; } .jcrop-dragbar.ord-w { margin-left: -4px; } /* The "jcrop-light" class/extension */ .jcrop-light .jcrop-vline, .jcrop-light .jcrop-hline { background: #ffffff; filter: alpha(opacity=70) !important; opacity: .70!important; } .jcrop-light .jcrop-handle { -moz-border-radius: 3px; -webkit-border-radius: 3px; background-color: #000000; border-color: #ffffff; border-radius: 3px; } /* The "jcrop-dark" class/extension */ .jcrop-dark .jcrop-vline, .jcrop-dark .jcrop-hline { background: #000000; filter: alpha(opacity=70) !important; opacity: 0.7 !important; } .jcrop-dark .jcrop-handle { -moz-border-radius: 3px; -webkit-border-radius: 3px; background-color: #ffffff; border-color: #000000; border-radius: 3px; } /* Simple macro to turn off the antlines */ .solid-line .jcrop-vline, .solid-line .jcrop-hline { background: #ffffff; } /* Fix for twitter bootstrap et al. */ .jcrop-holder img, img.jcrop-preview { max-width: none; } .uploadPics { position: relative; margin: 0 auto; width: 380px; background-color: #fff; border-top: 3px solid #ed2828; height: 460px; overflow: hidden; } .uploadPics > img { position: absolute; top: 20px; right: 10px; cursor: pointer; } .uploadPics .picTil { padding: 20px; font-size: 16px; color: #323232; border-bottom: 1px solid #f3f3f3; } .uploadPics .picCont { margin: 20px; padding: 15px; width: 300px; height: 337px; background-color: #f2f2f5; } .uploadPics .picCont > p { margin-top: 20px; text-align: center; } .uploadPics .picFooter { text-align: center; } .uploadPics .picFooter .btn { display: inline-block; margin: 20px; width: 130px; height: 35px; font-size: 18px; line-height: 35px; color: #fff; border-radius: 5px; cursor: pointer; } .uploadPics .picFooter .upload { background-color: #aaa; } .uploadPics .picFooter .confirm { background-color: #ed2828; } #myCan{ position: absolute; top: 50px; right: 50px; } </style> </head> <body> <div class="uploadPics"> <img src="../images/AvatarClose.png" alt="" onclick="ClosePage()" /> <div class="picTil">上传头像</div> <div class="picCont" style="width:300px;height:300px;margin:20px auto 0;padding:0;" > <div id=imgfield style=overflow:hidden;width:100%;height:100% ></div> </div> <div class="picFooter"> <input type="file" id="fileimg" name="fileimg" style="display:none" onchange="imgchange()" /> <span class="btn upload" onclick="getimg()">上传</span> <span class="btn confirm" onclick="subform()">确认</span> </div> </div> <canvas id="myCan" width="200" height="200"></canvas> </body> <script type="text/javascript" src="http://182.92.213.51:1070/html/js/inc/jquery-1.8.3.min.js"></script> <script type="text/javascript" src="http://182.92.213.51:1070/html/js/inc/jquery.Jcrop.js"></script> <script type="text/javascript"> function subform() { if($("#imgfield").html()){ //获取裁剪完后的base64图片url,转换为blob var data=document.getElementById("myCan").toDataURL(); var formData=new FormData(); formData.append("imageName",dataURLtoBlob(data)); var httprequest=new XMLHttpRequest(); var apiurl=""; //上传图片的api接口,自行填写 httprequest.open('POST',apiurl,true); httprequest.send(formData); httprequest.onreadystatechange= function () { if(httprequest.status==200 && httprequest.readyState==4){ var json=JSON.parse(httprequest.responseText); console.log(json) }else{ alert("上传图片失败!api错误") } }; }else{ alert("请选择图片!") } } function getimg() { $("#fileimg").click(); } function imgchange() { var localimg = $("#fileimg").get(0).files[0]; if(!localimg){ return; } var fileName = localimg.name; var fileSize = localimg.size; var fileType=fileName.substring(fileName.lastIndexOf('.'),fileName.length).toLowerCase(); if(fileType!='.gif' && fileType!='.jpeg' && fileType!='.png' && fileType!='.jpg') { alert("上传失败,请上传jpg,png格式的图片"); return; } var size=3*1024*1024; if(fileSize>size){ alert("上传失败,请上传3MB以内的图片。"); return; } var reader=new FileReader(); //将文件读取为DataURL reader.readAsDataURL(localimg); reader.onload= function (e) { var localimghtml = '<img id="cropbox" src="' + e.target.result + '" >'; $("#imgfield").html(localimghtml); initJcrop(); }; } function initJcrop(){ $('#cropbox').Jcrop({ onSelect: updateCoords, aspectRatio: 1, boxWidth: 300, boxHeight: 300 }, function () { //图片实际尺寸 var bb = this.getBounds(); var bWidth= Number(bb[0]) / 2; var bHeight= Number(bb[1]) / 2; this.setSelect([0, 0, bWidth,bHeight]); var ss = this.getWidgetSize(); var aheight = (300 - Number(ss[1])) / 2 + "px"; $(".jcrop-holder").css("margin-top", aheight); }); } function updateCoords(c){ // console.log(c); var img=document.getElementById("cropbox"); var ctx=document.getElementById("myCan").getContext("2d"); //img,开始剪切的x,Y坐标宽高,放置图像的x,y坐标宽高。 ctx.drawImage(img,c.x,c.y, c.w, c.h,0,0,200,200); } //**dataURL to blob** function dataURLtoBlob(dataurl) { var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], { type: mime }); } </script> </html>