Jcrop是一款優秀的jQuery插件,能夠很是方便地實現圖像裁剪,並且功能十分的強大。javascript
通常的狀況下,圖像裁剪的實現要通過兩次圖像上傳,第一次將圖片上傳到後臺,後臺返回一個連接,經過這個連接在本地實現預覽。第二次將圖片自己以及裁剪參數上傳到後臺,後臺進行裁剪,並保存在服務器。也就是說第一次的上傳是沒必要要的,用戶萬一中途取消了操做,那第一次的操做就徹底成了無用操做。並且增長了網絡的消耗,形成了沒必要要的浪費。通常這種狀況下,咱們會考慮第二次不進行上傳而使用第一次上傳的圖片,但這增長了技術難度,並且形成了更多的Exceptions的可能。事實css
上有更好的選擇,那就是FileAPI,它不進行上傳,圖片的預覽是經過將圖片加載到本地瀏覽器緩存實現的。咱們經過FileAPI獲取必要的參數,在用戶「下定決心」使用該圖的時候再進行上傳,能夠極大的下降多餘消耗,加強用戶體驗。html
要實現圖像裁剪上傳,首先要實現圖像本地預覽的功能。定義一個priviewImage.js文件,方便複用:html5
function previewImage(file, callback) { /* * file:file控件 prvid: 圖片預覽容器 */ /*if (file[0].fileSize() > 3 * FileAPI.MB) { alert("The uploading file size must less than 3MB!"); return; }*/ var tip = "Expect jpg or png or gif!"; // 設定提示信息 var filters = { "jpeg" : "/9j/4", "gif" : "R0lGOD", "png" : "iVBORw" } if (window.FileReader) { // html5方案 for (var i = 0, f; f = file.files[i]; i++) { var fr = new FileReader(); fr.onload = function(e) { var src = e.target.result; if (!validateImg(src)) { alert(tip); } else { showPrvImg(src); } } fr.readAsDataURL(f); } } else { // 降級處理 if (!/\.jpg$|\.png$|\.gif$/i.test(file.value)) { alert(tip); } else { showPrvImg(file.value); } } function validateImg(data) { var pos = data.indexOf(",") + 1; for ( var e in filters) { if (data.indexOf(filters[e]) === pos) { return e; } } return null; } function showPrvImg(src) { callback(src); } }
經過callback能夠拿到字節碼形式的圖片,將其設爲img標籤的src屬性,瀏覽器便可以顯示出來。如下是一個例子:java
<div> <p>預覽:</p> <div id="previewBox"> <img src="" id="previewImage" alt="預覽頭像"> </div> </div>
previewImage(file, function(src) { $("#previewImage").attr("src", src);}
如今來描述下Jcrop圖像裁剪上傳的基本流程:jquery
第一步:用戶點擊fileinput,選擇本地圖片,並經過FileAPI將該文件加載到瀏覽器緩存,最後造成網頁上的本地預覽圖片;ajax
第二步:Jcrop針對預覽圖片進行初始化,關於初始化的具體方法,我會在後面說到。這裏有一個難題,事實上解決方案是一個選擇器的問題,後面詳細說明,關於Jcrop的詳細使用方法,能夠自行百度,網上有不少的相關介紹;json
第三步:經過Jcrop將用戶的裁剪數據捕捉到hiddeninput中,這個即是Jcrop的核心,因此不須要咱們作過多的考慮;瀏覽器
第四步:用戶決定是應用操做仍是放棄操做。若放棄,則將DOM重置,若應用,則用ajaxFileUpload上傳圖片。緩存
如今來詳細說明各步驟的實現:
首先是文件的加載,須要的依賴有jQuery.js,Jcrop.js,ajaxFileUpload.js以及咱們先前定義的previewImage.js:
<link rel="stylesheet" href="css/jquery.Jcrop.min.css" type="text/css"> <script type="text/javascript" src="js/jquery-1.10.2.min.js"></script> <script type="text/javascript" src="js/jquery.Jcrop.min.js"></script> <script type="text/javascript" src="js/previewImage.js"></script> <script type="text/javascript" src="js/ajaxfileupload.js"></script>
基本的DOM模型:
<div> <input id="myImage" name="myImage" type="file" onchange="initImgForm(this)"> <button type="button" id="resetImgBtn">取消選擇</button> <button type="button" id="imgBtn">確認修改</button> <input type="hidden" id="offsetX" name="offsetX" value="0"> <input type="hidden" id="offsetY" name="offsetY" value="0"> <input type="hidden" id="width" name="width" value="120"> <input type="hidden" id="height" name="height" value="120"> </div>
說到這裏,我多嘴一句,button元素在使用的時候最好指定一下type="button",由於它在和form元素組合使用的時候,若不指定屬性,在某些瀏覽器中會觸發form的submit事件,形成一些沒必要要的錯誤。DOM還有一部分,預覽窗格:
<div> <p>預覽:</p> <div id="previewBox"> <img src="" id="previewImage" alt="預覽頭像"> </div> </div>
當用戶點擊fileinput的時候,將會調用initImgForm方法,完成圖片預覽以及Jcrop的初始化。Jcrop出事化的關鍵在於$.children()方法,直接針對父元素"#previewImage"會出現錯誤,同時也不可對其子元素<img>調用$.Jcrop方法,也會出現錯誤。
<script type="text/javascript"> var JcropApi, boundx, boundy; function initImgForm(file) { /* 驗證文件大小還未實現,服務器端最大Size 3MB,參閱 previewImage.js*/ previewImage(file, function(src) { $("#previewImage").attr("src", src); $("#previewBox").children().Jcrop({ onChange : showPreview, onSelect : showPreview, minSize : [ 120, 120 ], maxSize : [ 400, 400 ], aspectRatio : 1 }, function() { var bounds = this.getBounds(); boundx = bounds[0]; boundy = bounds[1]; JcropApi = this; }); }); } function showPreview(c) { var w = $("#previewImage").width(); var h = $("#previewImage").height(); var rx = w / c.w; var ry = h / c.h; $("#previewImage").css({ width : Math.round(rx * w) + "px", height : Math.round(ry * h) + "px", marginLeft : "-" + Math.round(rx * c.x) + "px", matginTop : "-" + Math.round(ry * c.y) + "py" }); $("#offsetX").val(c.x); $("#offsetY").val(c.y); $("#width").val(c.w); $("#height").val(c.h); } $("#resetImgBtn").on("click", function() { resetImg(); }); $("#imgBtn").on("click", function() { var params = {}; params.offsetX = $("#offsetX").val(); params.offsetY = $("#offsetY").val(); params.width = $("#width").val(); params.height = $("#height").val(); $.ajaxFileUpload({ url : "...",//定義你的上傳路徑 secureurl : false, fileElementId : "myImage", data : params, dataType : "json", success : function(json) { if (json.status) { $("#currentImage").attr("src", json.imgsrc); resetImg(); alert(json.message); } else { alert(json.message); } }, error : function() { alert("請求失敗"); } }); }); function resetImg() { $("#previewBox").empty(); var img = "<img id=\"previewImage\" src=\"\" alt=\"預覽頭像\">"; $("#previewBox").append(img); $("#myImage").val(""); JcropApi.destroy(); } </script>