js+java實現的頭像上傳和裁剪,完美相容各種瀏覽器
阿新 • • 發佈:2019-01-25
1.前端剪下效果使用jquery+js+div+css實現
其中有個js圖片剪下外掛叫ImgCropper,吃外掛與jquery外掛一起使用會有bug,被我修改後能相容jquery了
如果需要了解更多關於ImgCropper外掛使用,請檢視原始碼或百度看例子吧
下面是我修改後的ImgCropper+Resize+Drag的整合程式碼,使用時只需將程式碼打包後,通過script標籤引用即可
2.頭像剪下頁面我也進行了一些部件,佈局樣式是參考了百度頭像上傳佈局,上傳圖片使用了ajaxFileUpload.js外掛var isIE = (document.all) ? true : false; var isIE6 = isIE && ([/MSIE (\d)\.0/i.exec(navigator.userAgent)][0][1] == 6); var $getElem = function (id) { return "string" == typeof id ? document.getElementById(id) : id; }; var Class = { create: function() { return function() { this.initialize.apply(this, arguments); } } } var Extend = function(destination, source) { for (var property in source) { destination[property] = source[property]; } } var Bind = function(object, fun) { return function() { return fun.apply(object, arguments); } } var BindAsEventListener = function(object, fun) { var args = Array.prototype.slice.call(arguments).slice(2); return function(event) { return fun.apply(object, [event || window.event].concat(args)); } } var CurrentStyle = function(element){ return element.currentStyle || document.defaultView.getComputedStyle(element, null); } function addEventHandler(oTarget, sEventType, fnHandler) { if (oTarget.addEventListener) { oTarget.addEventListener(sEventType, fnHandler, false); } else if (oTarget.attachEvent) { oTarget.attachEvent("on" + sEventType, fnHandler); } else { oTarget["on" + sEventType] = fnHandler; } }; function removeEventHandler(oTarget, sEventType, fnHandler) { if (oTarget.removeEventListener) { oTarget.removeEventListener(sEventType, fnHandler, false); } else if (oTarget.detachEvent) { oTarget.detachEvent("on" + sEventType, fnHandler); } else { oTarget["on" + sEventType] = null; } }; //圖片切割 var ImgCropper = Class.create(); ImgCropper.prototype = { //容器物件,控制層,圖片地址 initialize: function(container, handle, url, options) { this._Container = $getElem(container);//容器物件 this._layHandle = $getElem(handle);//控制層 this.Url = url;//圖片地址 this._layBase = this._Container.appendChild(document.createElement("img"));//底層 this._layCropper = this._Container.appendChild(document.createElement("img"));//切割層 this._layCropper.onload = Bind(this, this.SetPos); //用來設定大小 this._tempImg = document.createElement("img"); this._tempImg.onload = Bind(this, this.SetSize); this.SetOptions(options); this.Opacity = Math.round(this.options.Opacity); this.Color = this.options.Color; this.Scale = !!this.options.Scale; this.Ratio = Math.max(this.options.Ratio, 0); this.Width = Math.round(this.options.Width); this.Height = Math.round(this.options.Height); //設定預覽物件 var oPreview = $getElem(this.options.Preview);//預覽物件 if(oPreview){ oPreview.style.position = "relative"; oPreview.style.overflow = "hidden"; this.viewWidth = Math.round(this.options.viewWidth); this.viewHeight = Math.round(this.options.viewHeight); //預覽圖片物件 this._view = oPreview.appendChild(document.createElement("img")); this._view.style.position = "absolute"; this._view.onload = Bind(this, this.SetPreview); } //設定拖放 this._drag = new Drag(this._layHandle, { Limit: true, onMove: Bind(this, this.SetPos), Transparent: true }); //設定縮放 this.Resize = !!this.options.Resize; if(this.Resize){ var op = this.options, _resize = new Resize(this._layHandle, { Max: true, onResize: Bind(this, this.SetPos) }); //設定縮放觸發物件 op.RightDown && (_resize.Set(op.RightDown, "right-down")); op.LeftDown && (_resize.Set(op.LeftDown, "left-down")); op.RightUp && (_resize.Set(op.RightUp, "right-up")); op.LeftUp && (_resize.Set(op.LeftUp, "left-up")); op.Right && (_resize.Set(op.Right, "right")); op.Left && (_resize.Set(op.Left, "left")); op.Down && (_resize.Set(op.Down, "down")); op.Up && (_resize.Set(op.Up, "up")); //最小範圍限制 this.Min = !!this.options.Min; this.minWidth = Math.round(this.options.minWidth); this.minHeight = Math.round(this.options.minHeight); //設定縮放物件 this._resize = _resize; } //設定樣式 this._Container.style.position = "relative"; this._Container.style.overflow = "hidden"; this._layHandle.style.zIndex = 200; this._layCropper.style.zIndex = 100; this._layBase.style.position = this._layCropper.style.position = "absolute"; this._layBase.style.top = this._layBase.style.left = this._layCropper.style.top = this._layCropper.style.left = 0;//對齊 //初始化設定 this.Init(); }, //設定預設屬性 SetOptions: function(options) { this.options = {//預設值 Opacity: 50,//透明度(0到100) Color: "",//背景色 Width: 0,//圖片高度 Height: 0,//圖片高度 //縮放觸發物件 Resize: false,//是否設定縮放 Right: "",//右邊縮放物件 Left: "",//左邊縮放物件 Up: "",//上邊縮放物件 Down: "",//下邊縮放物件 RightDown: "",//右下縮放物件 LeftDown: "",//左下縮放物件 RightUp: "",//右上縮放物件 LeftUp: "",//左上縮放物件 Min: false,//是否最小寬高限制(為true時下面min引數有用) minWidth: 50,//最小寬度 minHeight: 50,//最小高度 Scale: false,//是否按比例縮放 Ratio: 0,//縮放比例(寬/高) //預覽物件設定 Preview: "",//預覽物件 viewWidth: 0,//預覽寬度 viewHeight: 0//預覽高度 }; Extend(this.options, options || {}); }, //初始化物件 Init: function() { //設定背景色 this.Color && (this._Container.style.backgroundColor = this.Color); //設定圖片 this._tempImg.src = this._layBase.src = this._layCropper.src = this.Url; //設定透明 if(isIE){ this._layBase.style.filter = "alpha(opacity:" + this.Opacity + ")"; } else { this._layBase.style.opacity = this.Opacity / 100; } //設定預覽物件 this._view && (this._view.src = this.Url); //設定縮放 if(this.Resize){ with(this._resize){ Scale = this.Scale; Ratio = this.Ratio; Min = this.Min; minWidth = this.minWidth; minHeight = this.minHeight; } } }, //設定切割樣式 SetPos: function() { //ie6渲染bug if(isIE6){ with(this._layHandle.style){ zoom = .9; zoom = 1; }; }; //獲取位置引數 var p = this.GetPos(); //按拖放物件的引數進行切割 this._layCropper.style.clip = "rect(" + p.Top + "px " + (p.Left + p.Width) + "px " + (p.Top + p.Height) + "px " + p.Left + "px)"; //設定預覽 this.SetPreview(); }, //設定預覽效果 SetPreview: function() { if(this._view){ //預覽顯示的寬和高 var p = this.GetPos(), s = this.GetSize(p.Width, p.Height, this.viewWidth, this.viewHeight), scale = s.Height / p.Height; //按比例設定引數 var pHeight = this._layBase.height * scale, pWidth = this._layBase.width * scale, pTop = p.Top * scale, pLeft = p.Left * scale; //設定預覽物件 with(this._view.style){ //設定樣式 width = pWidth + "px"; height = pHeight + "px"; top = - pTop + "px "; left = - pLeft + "px"; //切割預覽圖 clip = "rect(" + pTop + "px " + (pLeft + s.Width) + "px " + (pTop + s.Height) + "px " + pLeft + "px)"; } } }, //設定圖片大小 SetSize: function() { var s = this.GetSize(this._tempImg.width, this._tempImg.height, this.Width, this.Height); //設定底圖和切割圖 this._layBase.style.width = this._layCropper.style.width = s.Width + "px"; this._layBase.style.height = this._layCropper.style.height = s.Height + "px"; //設定拖放範圍 this._drag.mxRight = s.Width; this._drag.mxBottom = s.Height; //設定縮放範圍 //if(this.Resize){ this._resize.mxRight = s.Width; this._resize.mxBottom = s.Height; } /*2015-9-6 15:45:16修改by wqj*/ if(this.Resize){ this._resize.mxRight = Math.round(s.Width); this._resize.mxBottom = Math.round(s.Height); } }, //獲取當前樣式 GetPos: function() { with(this._layHandle){ return { Top: offsetTop, Left: offsetLeft, Width: offsetWidth, Height: offsetHeight } } }, //獲取尺寸 GetSize: function(nowWidth, nowHeight, fixWidth, fixHeight) { var iWidth = nowWidth, iHeight = nowHeight, scale = iWidth / iHeight; //按比例設定 if(fixHeight){ iWidth = (iHeight = fixHeight) * scale; } if(fixWidth && (!fixHeight || iWidth > fixWidth)){ iHeight = (iWidth = fixWidth) / scale; } //返回尺寸物件 return { Width: iWidth, Height: iHeight } } }; //拖放程式 var Drag = Class.create(); Drag.prototype = { //拖放物件 initialize: function(drag, options) { this.Drag = $getElem(drag);//拖放物件 this._x = this._y = 0;//記錄滑鼠相對拖放物件的位置 this._marginLeft = this._marginTop = 0;//記錄margin //事件物件(用於繫結移除事件) this._fM = BindAsEventListener(this, this.Move); this._fS = Bind(this, this.Stop); this.SetOptions(options); this.Limit = !!this.options.Limit; this.mxLeft = parseInt(this.options.mxLeft); this.mxRight = parseInt(this.options.mxRight); this.mxTop = parseInt(this.options.mxTop); this.mxBottom = parseInt(this.options.mxBottom); this.LockX = !!this.options.LockX; this.LockY = !!this.options.LockY; this.Lock = !!this.options.Lock; this.onStart = this.options.onStart; this.onMove = this.options.onMove; this.onStop = this.options.onStop; this._Handle = $getElem(this.options.Handle) || this.Drag; this._mxContainer = $getElem(this.options.mxContainer) || null; this.Drag.style.position = "absolute"; //透明 if(isIE && !!this.options.Transparent){ //填充拖放物件 with(this._Handle.appendChild(document.createElement("div")).style){ width = height = "100%"; backgroundColor = "#fff"; filter = "alpha(opacity:0)"; fontSize = 0; } } //修正範圍 this.Repair(); addEventHandler(this._Handle, "mousedown", BindAsEventListener(this, this.Start)); }, //設定預設屬性 SetOptions: function(options) { this.options = {//預設值 Handle: "",//設定觸發物件(不設定則使用拖放物件) Limit: false,//是否設定範圍限制(為true時下面引數有用,可以是負數) mxLeft: 0,//左邊限制 mxRight: 9999,//右邊限制 mxTop: 0,//上邊限制 mxBottom: 9999,//下邊限制 mxContainer: "",//指定限制在容器內 LockX: false,//是否鎖定水平方向拖放 LockY: false,//是否鎖定垂直方向拖放 Lock: false,//是否鎖定 Transparent: false,//是否透明 onStart: function(){},//開始移動時執行 onMove: function(){},//移動時執行 onStop: function(){}//結束移動時執行 }; Extend(this.options, options || {}); }, //準備拖動 Start: function(oEvent) { if(this.Lock){ return; } this.Repair(); //記錄滑鼠相對拖放物件的位置 this._x = oEvent.clientX - this.Drag.offsetLeft; this._y = oEvent.clientY - this.Drag.offsetTop; //記錄margin this._marginLeft = parseInt(CurrentStyle(this.Drag).marginLeft) || 0; this._marginTop = parseInt(CurrentStyle(this.Drag).marginTop) || 0; //mousemove時移動 mouseup時停止 addEventHandler(document, "mousemove", this._fM); addEventHandler(document, "mouseup", this._fS); if(isIE){ //焦點丟失 addEventHandler(this._Handle, "losecapture", this._fS); //設定滑鼠捕獲 this._Handle.setCapture(); }else{ //焦點丟失 addEventHandler(window, "blur", this._fS); //阻止預設動作 oEvent.preventDefault(); }; //附加程式 this.onStart(); }, //修正範圍 Repair: function() { if(this.Limit){ //修正錯誤範圍引數 this.mxRight = Math.max(this.mxRight, this.mxLeft + this.Drag.offsetWidth); this.mxBottom = Math.max(this.mxBottom, this.mxTop + this.Drag.offsetHeight); //如果有容器必須設定position為relative或absolute來相對或絕對定位,並在獲取offset之前設定 !this._mxContainer || CurrentStyle(this._mxContainer).position == "relative" || CurrentStyle(this._mxContainer).position == "absolute" || (this._mxContainer.style.position = "relative"); } }, //拖動 Move: function(oEvent) { //判斷是否鎖定 if(this.Lock){ this.Stop(); return; }; //清除選擇 window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty(); //設定移動引數 var iLeft = oEvent.clientX - this._x, iTop = oEvent.clientY - this._y; //設定範圍限制 if(this.Limit){ //設定範圍引數 var mxLeft = this.mxLeft, mxRight = this.mxRight, mxTop = this.mxTop, mxBottom = this.mxBottom; //如果設定了容器,再修正範圍引數 if(!!this._mxContainer){ mxLeft = Math.max(mxLeft, 0); mxTop = Math.max(mxTop, 0); mxRight = Math.min(mxRight, this._mxContainer.clientWidth); mxBottom = Math.min(mxBottom, this._mxContainer.clientHeight); }; //修正移動引數 iLeft = Math.max(Math.min(iLeft, mxRight - this.Drag.offsetWidth), mxLeft); iTop = Math.max(Math.min(iTop, mxBottom - this.Drag.offsetHeight), mxTop); } //設定位置,並修正margin if(!this.LockX){ this.Drag.style.left = iLeft - this._marginLeft + "px"; } if(!this.LockY){ this.Drag.style.top = iTop - this._marginTop + "px"; } //附加程式 this.onMove(); }, //停止拖動 Stop: function() { //移除事件 removeEventHandler(document, "mousemove", this._fM); removeEventHandler(document, "mouseup", this._fS); if(isIE){ removeEventHandler(this._Handle, "losecapture", this._fS); this._Handle.releaseCapture(); }else{ removeEventHandler(window, "blur", this._fS); }; //附加程式 this.onStop(); } }; //縮放程式 var Resize = Class.create(); Resize.prototype = { //縮放物件 initialize: function(obj, options) { this._obj = $getElem(obj);//縮放物件 this._styleWidth = this._styleHeight = this._styleLeft = this._styleTop = 0;//樣式引數 this._sideRight = this._sideDown = this._sideLeft = this._sideUp = 0;//座標引數 this._fixLeft = this._fixTop = 0;//定位引數 this._scaleLeft = this._scaleTop = 0;//定位座標 this._mxSet = function(){};//範圍設定程式 this._mxRightWidth = this._mxDownHeight = this._mxUpHeight = this._mxLeftWidth = 0;//範圍引數 this._mxScaleWidth = this._mxScaleHeight = 0;//比例範圍引數 this._fun = function(){};//縮放執行程式 //獲取邊框寬度 var _style = CurrentStyle(this._obj); this._borderX = (parseInt(_style.borderLeftWidth) || 0) + (parseInt(_style.borderRightWidth) || 0); this._borderY = (parseInt(_style.borderTopWidth) || 0) + (parseInt(_style.borderBottomWidth) || 0); //事件物件(用於繫結移除事件) this._fR = BindAsEventListener(this, this.Resize); this._fS = Bind(this, this.Stop); this.SetOptions(options); //範圍限制 this.Max = !!this.options.Max; this._mxContainer = $getElem(this.options.mxContainer) || null; this.mxLeft = Math.round(this.options.mxLeft); this.mxRight = Math.round(this.options.mxRight); this.mxTop = Math.round(this.options.mxTop); this.mxBottom = Math.round(this.options.mxBottom); //寬高限制 this.Min = !!this.options.Min; this.minWidth = Math.round(this.options.minWidth); this.minHeight = Math.round(this.options.minHeight); //按比例縮放 this.Scale = !!this.options.Scale; this.Ratio = Math.max(this.options.Ratio, 0); this.onResize = this.options.onResize; this._obj.style.position = "absolute"; !this._mxContainer || CurrentStyle(this._mxContainer).position == "relative" || (this._mxContainer.style.position = "relative"); }, //設定預設屬性 SetOptions: function(options) { this.options = {//預設值 Max: false,//是否設定範圍限制(為true時下面mx引數有用) mxContainer:"",//指定限制在容器內 mxLeft: 0,//左邊限制 mxRight: 9999,//右邊限制 mxTop: 0,//上邊限制 mxBottom: 9999,//下邊限制 Min: false,//是否最小寬高限制(為true時下面min引數有用) minWidth: 50,//最小寬度 minHeight: 50,//最小高度 Scale: false,//是否按比例縮放 Ratio: 0,//縮放比例(寬/高) onResize: function(){}//縮放時執行 }; Extend(this.options, options || {}); }, //設定觸發物件 Set: function(resize, side) { var resize = $getElem(resize), fun; if(!resize) return; //根據方向設定 switch (side.toLowerCase()) { case "up" : fun = this.Up; break; case "down" : fun = this.Down; break; case "left" : fun = this.Left; break; case "right" : fun = this.Right; break; case "left-up" : fun = this.LeftUp; break; case "right-up" : fun = this.RightUp; break; case "left-down" : fun = this.LeftDown; break; case "right-down" : default : fun = this.RightDown; }; //設定觸發物件 addEventHandler(resize, "mousedown", BindAsEventListener(this, this.Start, fun)); }, //準備縮放 Start: function(e, fun, touch) { //防止冒泡(跟拖放配合時設定) e.stopPropagation ? e.stopPropagation() : (e.cancelBubble = true); //設定執行程式 this._fun = fun; //樣式引數值 this._styleWidth = this._obj.clientWidth; this._styleHeight = this._obj.clientHeight; this._styleLeft = this._obj.offsetLeft; this._styleTop = this._obj.offsetTop; //四條邊定位座標 this._sideLeft = e.clientX - this._styleWidth; this._sideRight = e.clientX + this._styleWidth; this._sideUp = e.clientY - this._styleHeight; this._sideDown = e.clientY + this._styleHeight; //top和left定位引數 this._fixLeft = this._styleLeft + this._styleWidth; this._fixTop = this._styleTop + this._styleHeight; //縮放比例 if(this.Scale){ //設定比例 this.Ratio = Math.max(this.Ratio, 0) || this._styleWidth / this._styleHeight; //left和top的定位座標 this._scaleLeft = this._styleLeft + this._styleWidth / 2; this._scaleTop = this._styleTop + this._styleHeight / 2; }; //範圍限制 if(this.Max){ //設定範圍引數 var mxLeft = this.mxLeft, mxRight = this.mxRight, mxTop = this.mxTop, mxBottom = this.mxBottom; //如果設定了容器,再修正範圍引數 if(!!this._mxContainer){ mxLeft = Math.max(mxLeft, 0); mxTop = Math.max(mxTop, 0); mxRight = Math.min(mxRight, this._mxContainer.clientWidth); mxBottom = Math.min(mxBottom, this._mxContainer.clientHeight); }; //根據最小值再修正 mxRight = Math.max(mxRight, mxLeft + (this.Min ? this.minWidth : 0) + this._borderX); mxBottom = Math.max(mxBottom, mxTop + (this.Min ? this.minHeight : 0) + this._borderY); //由於轉向時要重新設定所以寫成function形式 this._mxSet = function(){ this._mxRightWidth = mxRight - this._styleLeft - this._borderX; this._mxDownHeight = mxBottom - this._styleTop - this._borderY; this._mxUpHeight = Math.max(this._fixTop - mxTop, this.Min ? this.minHeight : 0); this._mxLeftWidth = Math.max(this._fixLeft - mxLeft, this.Min ? this.minWidth : 0); }; this._mxSet(); //有縮放比例下的範圍限制 if(this.Scale){ this._mxScaleWidth = Math.min(this._scaleLeft - mxLeft, mxRight - this._scaleLeft - this._borderX) * 2; this._mxScaleHeight = Math.min(this._scaleTop - mxTop, mxBottom - this._scaleTop - this._borderY) * 2; }; }; //mousemove時縮放 mouseup時停止 addEventHandler(document, "mousemove", this._fR); addEventHandler(document, "mouseup", this._fS); if(isIE){ addEventHandler(this._obj, "losecapture", this._fS); this._obj.setCapture(); }else{ addEventHandler(window, "blur", this._fS); e.preventDefault(); }; }, //縮放 Resize: function(e) { //清除選擇 window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty(); //執行縮放程式 this._fun(e); //設定樣式,變數必須大於等於0否則ie出錯 with(this._obj.style){ width = this._styleWidth + "px"; height = this._styleHeight + "px"; top = this._styleTop + "px"; left = this._styleLeft + "px"; } //附加程式 this.onResize(); }, //縮放程式 //上 Up: function(e) { this.RepairY(this._sideDown - e.clientY, this._mxUpHeight); this.RepairTop(); this.TurnDown(this.Down); }, //下 Down: function(e) { this.RepairY(e.clientY - this._sideUp, this._mxDownHeight); this.TurnUp(this.Up); }, //右 Right: function(e) { this.RepairX(e.clientX - this._sideLeft, this._mxRightWidth); this.TurnLeft(this.Left); }, //左 Left: function(e) { this.RepairX(this._sideRight - e.clientX, this._mxLeftWidth); this.RepairLeft(); this.TurnRight(this.Right); }, //右下 RightDown: function(e) { this.RepairAngle( e.clientX - this._sideLeft, this._mxRightWidth, e.clientY - this._sideUp, this._mxDownHeight ); this.TurnLeft(this.LeftDown) || this.Scale || this.TurnUp(this.RightUp); }, //右上 RightUp: function(e) { this.RepairAngle( e.clientX - this._sideLeft, this._mxRightWidth, this._sideDown - e.clientY, this._mxUpHeight ); this.RepairTop(); this.TurnLeft(this.LeftUp) || this.Scale || this.TurnDown(this.RightDown); }, //左下 LeftDown: function(e) { this.RepairAngle( this._sideRight - e.clientX, this._mxLeftWidth, e.clientY - this._sideUp, this._mxDownHeight ); this.RepairLeft(); this.TurnRight(this.RightDown) || this.Scale || this.TurnUp(this.LeftUp); }, //左上 LeftUp: function(e) { this.RepairAngle( this._sideRight - e.clientX, this._mxLeftWidth, this._sideDown - e.clientY, this._mxUpHeight ); this.RepairTop(); this.RepairLeft(); this.TurnRight(this.RightUp) || this.Scale || this.TurnDown(this.LeftDown); }, //修正程式 //水平方向 RepairX: function(iWidth, mxWidth) { iWidth = this.RepairWidth(iWidth, mxWidth); if(this.Scale){ var iHeight = this.RepairScaleHeight(iWidth); if(this.Max && iHeight > this._mxScaleHeight){ iHeight = this._mxScaleHeight; iWidth = this.RepairScaleWidth(iHeight); }else if(this.Min && iHeight < this.minHeight){ var tWidth = this.RepairScaleWidth(this.minHeight); if(tWidth < mxWidth){ iHeight = this.minHeight; iWidth = tWidth; } } this._styleHeight = iHeight; this._styleTop = this._scaleTop - iHeight / 2; } this._styleWidth = iWidth; }, //垂直方向 RepairY: function(iHeight, mxHeight) { iHeight = this.RepairHeight(iHeight, mxHeight); if(this.Scale){ var iWidth = this.RepairScaleWidth(iHeight); if(this.Max && iWidth > this._mxScaleWidth){ iWidth = this._mxScaleWidth; iHeight = this.RepairScaleHeight(iWidth); }else if(this.Min && iWidth < this.minWidth){ var tHeight = this.RepairScaleHeight(this.minWidth); if(tHeight < mxHeight){ iWidth = this.minWidth; iHeight = tHeight; } } this._styleWidth = iWidth; this._styleLeft = this._scaleLeft - iWidth / 2; } this._styleHeight = iHeight; }, //對角方向 RepairAngle: function(iWidth, mxWidth, iHeight, mxHeight) { iWidth = this.RepairWidth(iWidth, mxWidth); if(this.Scale){ iHeight = this.RepairScaleHeight(iWidth); if(this.Max && iHeight > mxHeight){ iHeight = mxHeight; iWidth = this.RepairScaleWidth(iHeight); }else if(this.Min && iHeight < this.minHeight){ var tWidth = this.RepairScaleWidth(this.minHeight); if(tWidth < mxWidth){ iHeight = this.minHeight; iWidth = tWidth; } } }else{ iHeight = this.RepairHeight(iHeight, mxHeight); } this._styleWidth = iWidth; this._styleHeight = iHeight; }, //top RepairTop: function() { this._styleTop = this._fixTop - this._styleHeight; }, //left RepairLeft: function() { this._styleLeft = this._fixLeft - this._styleWidth; }, //height RepairHeight: function(iHeight, mxHeight) { iHeight = Math.min(this.Max ? mxHeight : iHeight, iHeight); iHeight = Math.max(this.Min ? this.minHeight : iHeight, iHeight, 0); return iHeight; }, //width RepairWidth: function(iWidth, mxWidth) { iWidth = Math.min(this.Max ? mxWidth : iWidth, iWidth); iWidth = Math.max(this.Min ? this.minWidth : iWidth, iWidth, 0); return iWidth; }, //比例高度 RepairScaleHeight: function(iWidth) { return Math.max(Math.round((iWidth + this._borderX) / this.Ratio - this._borderY), 0); }, //比例寬度 RepairScaleWidth: function(iHeight) { return Math.max(Math.round((iHeight + this._borderY) * this.Ratio - this._borderX), 0); }, //轉向程式 //轉右 TurnRight: function(fun) { if(!(this.Min || this._styleWidth)){ this._fun = fun; this._sideLeft = this._sideRight; this.Max && this._mxSet(); return true; } }, //轉左 TurnLeft: function(fun) { if(!(this.Min || this._styleWidth)){ this._fun = fun; this._sideRight = this._sideLeft; this._fixLeft = this._styleLeft; this.Max && this._mxSet(); return true; } }, //轉上 TurnUp: function(fun) { if(!(this.Min || this._styleHeight)){ this._fun = fun; this._sideDown = this._sideUp; this._fixTop = this._styleTop; this.Max && this._mxSet(); return true; } }, //轉下 TurnDown: function(fun) { if(!(this.Min || this._styleHeight)){ this._fun = fun; this._sideUp = this._sideDown; this.Max && this._mxSet(); return true; } }, //停止縮放 Stop: function() { removeEventHandler(document, "mousemove", this._fR); removeEventHandler(document, "mouseup", this._fS); if(isIE){ removeEventHandler(this._obj, "losecapture", this._fS); this._obj.releaseCapture(); }else{ removeEventHandler(window, "blur", this._fS); } } };
需要注意的是:
a.ajaxFileUpload外掛上傳圖片,服務端返回的json時,response需要設定contentType為text/html;charset=UTF-8,不然ajaxFileUpload外掛不會靜success回撥方法,除錯ajaxFileUpload可以看返回的json被加上了pre標籤,也可以在uploadHttpData屬性定義裡將pre標籤去除
b.使用ajaxFileUpload外掛時,還可能遇見一個錯誤就是jQuery.handleError 方法未定義,由於jquery1.4.2以後的版本都把這個方法去掉了,所以需要我們自己將1.4.1版本的handleError方法copy到jquery架包中或ajaxFileUpload架包中,我是copy到ajaxFileUpload架包中的
新增handleError方法後的ajaxFileUpload程式碼:
jQuery.extend({ createUploadIframe: function(id, uri) { //create frame var frameId = 'jUploadFrame' + id; if(window.ActiveXObject) { var io = document.createElement('<iframe id="' + frameId + '" name="' + frameId + '" />'); if(typeof uri== 'boolean'){ io.src = 'javascript:false'; } else if(typeof uri== 'string'){ io.src = uri; } } else { var io = document.createElement('iframe'); io.id = frameId; io.name = frameId; } io.style.position = 'absolute'; io.style.top = '-1000px'; io.style.left = '-1000px'; document.body.appendChild(io); return io }, createUploadForm: function(id, fileElementId) { //create form var formId = 'jUploadForm' + id; var fileId = 'jUploadFile' + id; var form = $('<form action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>'); var oldElement = $('#' + fileElementId); var newElement = $(oldElement).clone(); $(oldElement).attr('id', fileId); $(oldElement).before(newElement); $(oldElement).appendTo(form); //set attributes $(form).css('position', 'absolute'); $(form).css('top', '-1200px'); $(form).css('left', '-1200px'); $(form).appendTo('body'); return form; }, ajaxFileUpload: function(s) { // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout s = jQuery.extend({}, jQuery.ajaxSettings, s); var id = s.fileElementId; var form = jQuery.createUploadForm(id, s.fileElementId); var io = jQuery.createUploadIframe(id, s.secureuri); var frameId = 'jUploadFrame' + id; var formId = 'jUploadForm' + id; // Watch for a new set of requests if ( s.global && ! jQuery.active++ ) { jQuery.event.trigger( "ajaxStart" ); } var requestDone = false; // Create the request object var xml = {} if ( s.global ) jQuery.event.trigger("ajaxSend", [xml, s]); // Wait for a response to come back var uploadCallback = function(isTimeout) { var io = document.getElementById(frameId); try { if(io.contentWindow) { xml.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null; xml.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document; }else if(io.contentDocument) { xml.responseText = io.contentDocument.document.body?io.contentDocument.document.body.innerHTML:null; xml.responseXML = io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document; } }catch(e) { jQuery.handleError(s, xml, null, e); } if ( xml || isTimeout == "timeout") { requestDone = true; var status; try { status = isTimeout != "timeout" ? "success" : "error"; // Make sure that the request was successful or notmodified if ( status != "error" ) { // process the data (runs the xml through httpData regardless of callback) var data = jQuery.uploadHttpData( xml, s.dataType ); // If a local callback was specified, fire it and pass it the data if ( s.success ) s.success( data, status ); // Fire the global callback if( s.global ) jQuery.event.trigger( "ajaxSuccess", [xml, s] ); } else jQuery.handleError(s, xml, status); } catch(e) { status = "error"; jQuery.handleError(s, xml, status, e); } // The request was completed if( s.global ) jQuery.event.trigger( "ajaxComplete", [xml, s] ); // Handle the global AJAX counter if ( s.global && ! --jQuery.active ) jQuery.event.trigger( "ajaxStop" ); // Process result if ( s.complete ) s.complete(xml, status); jQuery(io).unbind() setTimeout(function() { try { $(io).remove(); $(form).remove(); } catch(e) { jQuery.handleError(s, xml, null, e); } }, 100) xml = null } } // Timeout checker if ( s.timeout > 0 ) { setTimeout(function(){ // Check to see if the request is still happening if( !requestDone ) uploadCallback( "timeout" ); }, s.timeout); } try { // var io = $('#' + frameId); var form = $('#' + formId); $(form).attr('action', s.url); $(form).attr('method', 'POST'); $(form).attr('target', frameId); if(form.encoding) { form.encoding = 'multipart/form-data'; } else { form.enctype = 'multipart/form-data'; } $(form).submit(); } catch(e) { jQuery.handleError(s, xml, null, e); } if(window.attachEvent){ document.getElementById(frameId).attachEvent('onload', uploadCallback); } else{ document.getElementById(frameId).addEventListener('load', uploadCallback, false); } return {abort: function () {}}; }, uploadHttpData: function( r, type ) { var data = !type; data = type == "xml" || data ? r.responseXML : r.responseText; // If the type is "script", eval it in global context if ( type == "script" ) jQuery.globalEval( data ); // Get the JavaScript object, if JSON is used. if ( type == "json" ) eval( "data = " + data ); // evaluate scripts within html if ( type == "html" ) jQuery("<div>").html(data).evalScripts(); //alert($('param', data).each(function(){alert($(this).attr('value'));})); return data; }, handleError: function( s, xhr, status, e ) { // If a local callback was specified, fire it if ( s.error ) { s.error.call( s.context || s, xhr, status, e ); } // Fire the global callback if ( s.global ) { (s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] ); } } });
頁面佈局如下
擷取頁面佈局原始碼
<pre name="code" class="html"><%@ page language="java" import="java.util.*" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:set var="ctxPath" value="${pageContext.request.contextPath}" ></c:set>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>圖片裁剪及上傳</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /> -->
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
<style type="text/css">
body,ul,li,h1,h2,h3,h4,h5,h6,p,form,dl,dt,dd,input,label,span,img{margin: 0px;padding: 0px; list-style:none outside none;}
body,button,input,select,textarea{font:12px/1.5 Tahoma,Helvetica,Arial,"宋體",sans-serif; color:#333;}
a{ text-decoration:none;color:#333;}
a:hover{text-decoration:none;color:#C00;}
.passPortraitWrapper{
}
.passPortraitBox{
width:680px;
margin:0px auto;
padding:10px;
overflow:hidden;
}
.passPortraitLeftSide{
display:inline;
float:left;
width:440px;
}
.selectPortaitLabel{
position:relative;
padding-bottom:10px;
}
.portraitFile{
height:38px;
line-height:38px;
width:130px;
position:absolute;
left:0px;
overflow:hidden;
font-size:24px;
opacity: 0;
filter: alpha(opacity=0);
}
.portraitBtn{
height:38px;
line-height:38px;
width:130px;
border: medium none;
background: transparent url('${ctxPath}/resources/images/ImgCropper/crop_img_sprite.png') no-repeat scroll 0% 0%;
}
.selectPortraitBtn{
background-position:0px 0px;
color:#666;
}
.selectPortaitNote{
display:inline-block;
position:absolute;
font-size:12px;
height:24px;
line-height:24px;
color:#999;
text-align:left;
top: 8px;
left: 140px;
}
.portraitFilePath{
display:block;
color:#999;
line-height:20px;
}
.portraitBox{
height:300px;
width:440px;
overflow:auto;
}
.portraitBG{
height:300px;
line-height:300px;
width:400px;
background:#E2E2E2 none repeat scroll 0% 0%;
position:absolute;
}
.portraitLoad{
height:16px;
width:16px;
font-size:0px;
position:absolute;
top:142px;
left:192px;
z-index:100;
}
.portraitPosition{
position: relative;
left: 50%;
top: 50%;
}
.portraitSelection{
width: 404px;
height: 304px;
position: absolute;
top: -2px;
left: -2px;
cursor: crosshair;
z-index: 290;
}
.portraitImg{
}
.okPortraitLabel{
padding-top:10px;
position:relative;
}
.okPortraitBtn{
background-position:0px -38px;
color:#fefefe;
}
.okPortraitBtn_disable{
background-position:0px -151px;
}
.passPortraitRightSide{
display:inline;
float:right;
width:180px;
height:390px;
border-left:1px solid #E5E5E5;
padding-left:36px;
margin-left:10px;
position:relative;
}
.portraitPreviewBox{
position:absolute;
top:0px;
}
.portraitPreviewLabel{
height:38px;
line-height:38px;
font-size:14px;
color:#666;
}
.portraitPreviewContent{
height:160px;
width:160px;
border:1px dashed #000;
}
.portraitPresetBox{
position:absolute;
bottom:0px;
}
.portraitPresetLabel{
height:38px;
line-height:38px;
font-size:14px;
color:#666;
}
.portraitPresetContent{
width:180px;
height:80px;
overflow:hidden;
position:relative;
border:1px solid #eee;
}
.portraitPresetUl{
width:1000px;
}
.portraitPresetLi{
height:80px;
width:80px;
float:left;
}
.portraitPresetArrowBox{
width:180px;
position:absolute;
right:0px;
top:0px;
}
.portraitPresetArrow{
width:16px;
height:16px;
position:absolute;
}
.portraitPresetPrep{
background:url('${ctxPath}/resources/images/ImgCropper/previous.png') no-repeat;
left:0px;
top:32px
}
.portraitPresetNext{
background:url('${ctxPath}/resources/images/ImgCropper/next.png') no-repeat;
right:0px;
top:32px
}
.portraitPresetArrowBG{
width:16px;
height:80px;
position:absolute;
top:0px;
}
.portraitPresetPrepBG{
background:#777;
left:0px;
}
.portraitPresetNextBG{
background:#777;
right:0px;
}
.msg_content{
height:20px;
line-height:20px;
text-align:left;
color:#999;
position:absolute;
padding-left:20px;
top:18px;
left:140px;
}
.msg_icon{
width:16px;
height:16px;
font-size:0px;
position:absolute;
top:2px;
left:2px;
}
.msg_icon_ok{
background:url('${ctxPath}/resources/images/icons/ok.gif') no-repeat;
}
.msg_icon_warning{
background:url('${ctxPath}/resources/images/icons/warning.gif') no-repeat;
}
.msg_icon_info{
background:url('${ctxPath}/resources/images/icons/info.gif') no-repeat;
}
.imgViewBG{
height:300px;
background:#E2E2E2;
position:relative;
}
#imgView{
}
/*頁籤佈局開始*/
.tab_wrap{
}
.tab_nav_group{
background:#ccc;
overflow:hidden;
}
.tab_nav_ul{
}
.tab_nav_li{
height:24px;
line-height:24px;
padding:0px 10px;
border-right:1px solid #999;
float:left;
cursor:pointer;
}
.tab_nav_cuur{
background:#fff;
}
.tab_content{
overflow:hidden;
}
/*頁籤佈局結束*/
#rRightDown,#rLeftDown,#rLeftUp,#rRightUp,#rRight,#rLeft,#rUp,#rDown{
position:absolute;
background:#FFF;
border: 1px solid #333;
width: 6px;
height: 6px;
z-index:500;
font-size:0;
opacity: 0.5;
filter:alpha(opacity=50);
}
#rLeftDown,#rRightUp{cursor:ne-resize;}
#rRightDown,#rLeftUp{cursor:nw-resize;}
#rRight,#rLeft{cursor:e-resize;}
#rUp,#rDown{cursor:n-resize;}
#rLeftDown{left:-4px;bottom:-4px;}
#rRightUp{right:-4px;top:-4px;}
#rRightDown{right:-4px;bottom:-4px;background-color:#00F;}
#rLeftUp{left:-4px;top:-4px;}
#rRight{right:-4px;top:50%;margin-top:-4px;}
#rLeft{left:-4px;top:50%;margin-top:-4px;}
#rUp{top:-4px;left:50%;margin-left:-4px;}
#rDown{bottom:-4px;left:50%;margin-left:-4px;}
#bgDiv{position:relative;}
#dragDiv{border:1px dashed #000; width:100px; height:100px; top:0px; left:0px; cursor:move;position:absolute; }
</style>
<!-- 匯入js架包 -->
<script type="text/javascript" src="${ctxPath}/resources/js/jquery/jquery-1.9.1.js"></script>
<script type="text/javascript" src="${ctxPath}/resources/js/ImgCropper/ImgCropper-integration.js" ></script>
<script type="text/javascript" src="${ctxPath}/resources/js/util/ajaxFileUpload.js" ></script>
<script type="text/javascript" src="${ctxPath}/resources/js/imgReady/imgReady.js" ></script>
<script type="text/javascript">
var requestObj = {
attachAction:"${ctxPath}/uploadController?action=uploadAttach",
clipAction:"${ctxPath}/uploadController?action=clipImg"
};
var backImage = {id:"",url:"",clipId:"",clipUrl:""};
//頁籤標記
var tabFlag = 0;
var msgObj = {
'0': '成功上傳圖片',
'1': '圖片剪下成功',
'2': '請選擇裁剪區域',
'3': '請上傳正確格式圖片',
'4': '上傳檔案異常',
errnoErrno: 5,
successErrno: 0,
errnoPortraitMsg: '獲取圖片失敗',
errImgMsg: '請上傳正確格式圖片',
errCropMsg: '請選擇裁剪區域',
errUploadMsg: '上傳失敗'
};
var ic , scale = 1;
/* function selectImgFile(){
document.getElementById("fileImg").click();
} */
function uploadImg(file){
var fileId = file.id;
if(!validateImg(file)){
return;
}
if(tabFlag == 0){
$("#portraitLoad1").css("display","block");
$("#bgDiv").css("display","none");
}else{
$("#portraitLoad2").css("display","block");
$("#imgView").css("display","none");
}
$.ajaxFileUpload({
url: requestObj.attachAction,
fileElementId: fileId,
dataType: 'json',
data: {},
success: function (m, l) {
if (m.errno == msgObj.successErrno) {
backImage.id = m.picId;
backImage.clipId = m.picId;
backImage.url = decodeURIComponent(decodeURIComponent(m.portraitUrl));
backImage.clipUrl = decodeURIComponent(decodeURIComponent(m.portraitUrl));
if(tabFlag == 0){
showCrop();
$("#clip_ok").removeClass("okPortraitBtn_disable");
$("#file_btn1").val("重新選擇");
}else{
showImgView();
$("#upload_ok").removeClass("okPortraitBtn_disable");
$("#file_btn2").val("重新選擇");
}
showPromptInfo(m.errno, "");
} else {
if (m.errno == 1) {
showPromptInfo(m.errno, msgObj.errUploadMsg);
} else {
showPromptInfo(m.errno, msgObj[m.errno] || msgObj.errUploadMsg);
}
}
}
});
}
function showCrop(){
$("#portraitLoad1").css("display","none");
var url = backImage.clipUrl;
var containerWidth = 400;
var containerHeight = 300;
var widthScale = 1.0 ,heightScale = 1.0;
//圖片在div中的高寬度
var imgBoxHeight = 0,imgBoxWidth = 0;
//圖片的實際高寬
var imgHeight = 0;
var imgWidth = 0;
//載入圖片高度寬度
imgReady(url,function(){
imgHeight = this.height;
imgWidth = this.width;
if(imgHeight > 0 && imgWidth > 0){
widthScale = containerWidth / imgWidth;
heightScale = containerHeight / imgHeight;
}
if(widthScale >= heightScale){
scale = heightScale;
}else{
scale = widthScale;
}
imgBoxHeight = Math.round(scale * imgHeight);
imgBoxWidth = Math.round(scale * imgWidth);
$("#bgDiv").width(imgBoxWidth);
$("#bgDiv").height(imgBoxHeight);
$("#bgDiv").css("margin-left",-imgBoxWidth / 2);
$("#bgDiv").css("margin-top",-imgBoxHeight / 2);
$("#bgDiv").css("display","block");
var dragDivHtmlStr = ''+
'<div id="dragDiv">'+
'<div id="rRightDown"> </div>'+
'<div id="rLeftDown"> </div>'+
'<div id="rRightUp"> </div>'+
'<div id="rLeftUp"> </div>'+
'<div id="rRight"> </div>'+
'<div id="rLeft"> </div>'+
'<div id="rUp"> </div>'+
'<div id="rDown"></div>'+
'</div>';
var dragDivObj = $(dragDivHtmlStr);
$("#bgDiv").html("");
$("#bgDiv").append(dragDivObj);
//移除原有的img標籤
$("#bgDiv").find("img").remove();
$("#viewDiv").find("img").remove();
ic = new ImgCropper("bgDiv", "dragDiv", url, {
Width: imgBoxWidth, Height: imgBoxHeight , Color: "#FFF",
Resize: true,
Right: "rRight", Left: "rLeft", Up: "rUp", Down: "rDown",
RightDown: "rRightDown", LeftDown: "rLeftDown", RightUp: "rRightUp", LeftUp: "rLeftUp",
Preview: "viewDiv", viewWidth: 160, viewHeight: 160
});
});
}
function showImgView(){
$("#portraitLoad2").css("display","none");
var url = backImage.url;
var containerWidth = 400;
var containerHeight = 300;
var widthScale = 1.0 ,heightScale = 1.0;
var imgBoxHeight = 0,imgBoxWidth = 0;
//圖片的實際高寬
var imgHeight = 0;
var imgWidth = 0;
//載入圖片高度寬度
imgReady(url,function(){
imgHeight = this.height;
imgWidth = this.width;
if(imgHeight > 0 && imgWidth > 0){
widthScale = containerWidth / imgWidth;
heightScale = containerHeight / imgHeight;
}
if(widthScale >= heightScale){
scale = heightScale;
}else{
scale = widthScale;
}
imgBoxHeight = Math.round(scale * imgHeight);
imgBoxWidth = Math.round(scale * imgWidth);
$("#imgView").width(imgBoxWidth);
$("#imgView").height(imgBoxHeight);
$("#imgView").css("margin-left",-imgBoxWidth / 2);
$("#imgView").css("margin-top",-imgBoxHeight / 2);
$("#imgView").css("display","block");
$("#imgView").html("");
var img = $("<img src=''/>");
img.attr("height",imgBoxHeight);
img.attr("width",imgBoxWidth);
img.attr("src",url);
$("#imgView").append(img);
});
}
function showPromptInfo(errno,msg){
if(!msg){
msg = msgObj[errno];
}
if(tabFlag == 0){
$("#msg_content1").find("span").text(msg);
$("#msg_content1").find("i").removeClass();
$("#msg_content1").find("i").addClass("msg_icon");
if(errno == msgObj.successErrno){
$("#msg_content1").find("i").addClass("msg_icon_ok");
}else if(errno == msgObj.errnoErrno){
$("#msg_content1").find("i").addClass("msg_icon_warning");
}else{
$("#msg_content1").find("i").addClass("msg_icon_info");
}
$("#msg_content1").css("display","block");
setTimeout("hiddenDiv('msg_content1')",1000);
}else{
$("#msg_content2").find("span").text(msg);
$("#msg_content2").find("i").removeClass();
$("#msg_content2").find("i").addClass("msg_icon");
if(errno == msgObj.successErrno){
$("#msg_content2").find("i").addClass("msg_icon_ok");
}else if(errno == msgObj.errnoErrno){
$("#msg_content2").find("i").addClass("msg_icon_warning");
}else{
$("#msg_content2").find("i").addClass("msg_icon_info");
}
$("#msg_content2").css("display","block");
setTimeout("hiddenDiv('msg_content2')",1000);
}
}
function hiddenDiv(divId){
$("#"+divId).css("display","none");
}
//驗證圖片格式必須為jpg|jpeg|gif|png|bmp
function validateImg (j) {
h = j.value || '';
if (/^.*?\.(jpg|jpeg|gif|png|bmp)$/.test(h.toLowerCase())) {
return true;
} else {
showPromptInfo(msgObj.errnoErrno, msgObj.errImgMsg);
return false;
}
}
//js程式碼
$(document).ready(function(){
//點選頁籤切換內容
$(".tab_nav_li").click(function(){
var contentId = $(this).attr("cid");
if($(this).attr("id") && $(this).attr("id").indexOf("1") != -1){
tabFlag = 0 ;
}else{
tabFlag = 1;
}
$(".tab_content").css("display","none");
$(".tab_nav_li").removeClass("tab_nav_cuur");
$(this).addClass("tab_nav_cuur");
$("#"+contentId).css("display","block");
});
$("#clip_ok").click(function(){
if(!$(this).hasClass("okPortraitBtn_disable")){
var clipWidth = 0 , clipHeight = 0;
var clipTop = 0 , clipLeft = 0;
if(ic){
var posObj = ic.GetPos();
clipTop = Math.round(posObj.Top / scale);
clipLeft = Math.round(posObj.Left / scale);
clipWidth = Math.round(posObj.Width / scale);
clipHeight = Math.round(posObj.Height / scale);
if(clipWidth < 1 || clipHeight < 1 ){
showPromptInfo(2,"");
}else{
var picId = backImage.id;
var clipSubmitData = {attachId:picId,x:clipLeft,y:clipTop,width:clipWidth,height:clipHeight};
$.post(requestObj.clipAction, clipSubmitData, function(data){
if(data){
backImage.clipUrl = decodeURIComponent(decodeURIComponent(data.url));
showPromptInfo(data.errno,"");
$("#testImg").attr("src",backImage.clipUrl);
}
});
}
}else{
showPromptInfo(5,"請先選擇需要剪下的圖片");
}
}
});
$("#upload_ok").click(function(){
//判斷是否有
if(!$(this).hasClass("okPortraitBtn_disable")){
showPromptInfo(0,"圖片已儲存");
$("#testImg").attr("src",backImage.clipUrl);
}
});
$(".portraitLoad").css("display","none");
$(".okPortraitBtn").addClass("okPortraitBtn_disable");
});
</script>
</head>
<body>
<div class="passPortraitWrapper">
<div class="tab_wrap">
<div class="tab_nav_group">
<ul class="tab_nav_ul">
<li class="tab_nav_li tab_nav_cuur" id="tab_1" cid="clip_img">圖片剪下</li>
<li class="tab_nav_li" id="tab_2" cid="upload_img">圖片上傳</li>
</ul>
</div>
<div class="tab_content_group">
<div class="tab_content" style="display:block;" id="clip_img">
<div class="passPortraitBox">
<div class="passPortraitLeftSide">
<div class="selectPortaitLabel">
<input type="file" name="file" id="fileImg" class="portraitFile" onchange="uploadImg(this)"/>
<input type="button" class="portraitBtn selectPortraitBtn" id="file_btn1" value="選擇圖片" onclick=""/>
<span class="selectPortaitNote">支援jpg、jpeg、gif、png、bmp格式的圖片</span>
</div>
<div id="imgPath" class="portraitFilePath"></div>
<div class="portraitBox">
<div class="portraitBG">
<div id="portraitLoad1" class="portraitLoad" >
<img src="${ctxPath}/resources/images/loading/zoomloader.gif" height="16" width="16" />
</div>
<div style="display:none;" class="portraitPosition" id="bgDiv">
</div>
</div>
</div>
<div class="okPortraitLabel" >
<input type="button" id="clip_ok" value="確定" class="portraitBtn okPortraitBtn okPortraitBtn_disable"/>
<span class="msg_content" id="msg_content1" ><i class="msg_icon" ></i><span></span></span>
</div>
</div>
<div class="passPortraitRightSide">
<div class="portraitPreviewBox">
<div class="portraitPreviewLabel">頭像預覽</div>
<div class="portraitPreviewContent" id="viewDiv"></div>
</div>
</div>
</div>
</div>
<div class="tab_content" style="display:none;" id="upload_img">
<div style="margin:0px auto;width:400px;padding:10px;">
<div class="selectPortaitLabel">
<input type="file" name="file" id="fileImg2" class="portraitFile" onchange="uploadImg(this)"/>
<input type="button" class="portraitBtn selectPortraitBtn" id="file_btn2" value="選擇圖片" onclick=""/>
<span class="selectPortaitNote">支援jpg、jpeg、gif、png、bmp格式的圖片</span>
</div>
<div class="imgViewBG" >
<div id="portraitLoad2" class="portraitLoad" >
<img src="${ctxPath}/resources/images/loading/zoomloader.gif" height="16" width="16" />
</div>
<div id="imgView" style="display:none;position:absolute;z-index:200;background:#fff;left:50%;top:50%;"></div>
</div>
<div class="okPortraitLabel">
<input type="button" value="確定" id="upload_ok" class="portraitBtn okPortraitBtn okPortraitBtn_disable"/>
<span class="msg_content" id="msg_content2" ><i class="msg_icon" ></i><span></span></span>
</div>
</div>
</div>
</div>
</div>
<div class="portraitParmDiv">
</div>
</div>
<div style="clear:both;">
<img src="" id="testImg" />
</div>
<script type="text/javascript">
/* var ic = new ImgCropper("bgDiv", "dragDiv", "http://images.cnblogs.com/cnblogs_com/cloudgamer/143727/r_xx2.jpg", {
Width: 224, Height: 300, Color: "#000",
Resize: true,
Right: "rRight", Left: "rLeft", Up: "rUp", Down: "rDown",
RightDown: "rRightDown", LeftDown: "rLeftDown", RightUp: "rRightUp", LeftUp: "rLeftUp",
Preview: "viewDiv", viewWidth: 160, viewHeight: 160
}); */
</script>
</body>
</html>
3.由於上傳圖片成功後,頁面需要重新計算圖片的高寬,保證能放入400*300的div中,還是用一個計算圖片高寬的imgReady外掛,原始碼來至於網路
程式碼如下:
// 更新:
// 05.27: 1、保證回撥執行順序:error > ready > load;2、回撥函式this指向img本身
// 04-02: 1、增加圖片完全載入後的回撥 2、提高效能
/**
* 圖片頭資料載入就緒事件 - 更快獲取圖片尺寸
* @version 2011.05.27
* @see http://blog.phpdr.net/js-get-image-size.html
* @param {String} 圖片路徑
* @param {Function} 尺寸就緒
* @param {Function} 載入完畢 (可選)
* @param {Function} 載入錯誤 (可選)
* @example imgReady('http://www.google.com.hk/intl/zh-CN/images/logo_cn.png', function () {
alert('size ready: width=' + this.width + '; height=' + this.height);
});
*/
var imgReady = (function () {
var list = [], intervalId = null,
// 用來執行佇列
tick = function () {
var i = 0;
for (; i < list.length; i++) {
list[i].end ? list.splice(i--, 1) : list[i]();
};
!list.length && stop();
},
// 停止所有定時器佇列
stop = function () {
clearInterval(intervalId);
intervalId = null;
};
return function (url, ready, load, error) {
var onready, width, height, newWidth, newHeight,
img = new Image();
img.src = url;
// 如果圖片被快取,則直接返回快取資料
if (img.complete) {
ready.call(img);
load && load.call(img);
return;
};
width = img.width;
height = img.height;
// 載入錯誤後的事件
img.onerror = function () {
error && error.call(img);
onready.end = true;
img = img.onload = img.onerror = null;
};
// 圖片尺寸就緒
onready = function () {
newWidth = img.width;
newHeight = img.height;
if (newWidth !== width || newHeight !== height ||
// 如果圖片已經在其他地方載入可使用面積檢測
newWidth * newHeight > 1024
) {
ready.call(img);
onready.end = true;
};
};
onready();
// 完全載入完畢的事件
img.onload = function () {
// onload在定時器時間差範圍內可能比onready快
// 這裡進行檢查並保證onready優先執行
!onready.end && onready();
load && load.call(img);
// IE gif動畫會迴圈執行onload,置空onload即可
img = img.onload = img.onerror = null;
};
// 加入佇列中定期執行
if (!onready.end) {
list.push(onready);
// 無論何時只允許出現一個定時器,減少瀏覽器效能損耗
if (intervalId === null) intervalId = setInterval(tick, 40);
};
};
})();
4.下面就是java服務端的servlet程式碼,服務端實現上傳使用commons-fileupload-1.2.2.jar,commons-io-2.0.1.jar
下面是servlet的程式碼:
package com.wqjweb.controller;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.json.simple.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import com.wqjweb.entry.Attachment;
import com.wqjweb.service.AttachmentService;
import com.wqjweb.util.date.DateUtil;
import com.wqjweb.util.file.FileUtil;
import com.wqjweb.util.image.ImgCutUtil;
import com.wqjweb.util.string.IDGenerator;
import com.wqjweb.util.string.StringUtil;
@Controller
public class UploadAttachController extends AutowiredHttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
@Autowired
private AttachmentService attachmentService;
private ServletContext ctx;
private String savePath;
@Override
public void init(ServletConfig config) throws ServletException {
// 在web.xml中設定的一個初始化引數
savePath = config.getInitParameter("savePath");
ctx = config.getServletContext();
super.init(config);
}
/**
* @return the attachmentService
*/
public AttachmentService getAttachmentService() {
return attachmentService;
}
/**
* @param attachmentService the attachmentService to set
*/
public void setAttachmentService(AttachmentService attachmentService) {
this.attachmentService = attachmentService;
}
@Override
public void servlet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
String action = StringUtil.trimStr(request.getParameter("action"));
if("uploadAction".equals(action)){
this.uploadAction(request, response);
}else if("test".equals(action)){
this.testResponse(request, response);
}else if("uploadAttach".equals(action)){
this.uploadAttach(request, response);
}else if("getAttachFile".equals(action)){
this.getAttachFile(request, response);
}else if("getImageFile".equals(action)){
this.getImageFile(request, response);
}else if("testURLDecoder".equals(action)){
this.testURLDecoder(request, response);
}else if("clipImg".equals(action)){
this.clipImg(request, response);
}
}
private void uploadAction(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
try{
List<FileItem> fileItemList = upload.parseRequest(request);
Iterator<FileItem> fileItemIter = fileItemList.iterator();
while(fileItemIter.hasNext()){
FileItem fileItem = fileItemIter.next();
//判斷是否表單提交的引數
if(fileItem.isFormField()){
System.out.println("表單引數名:"+fileItem.getFieldName()+"屬性值:"+fileItem.getString("utf-8"));
}else{
if(!"".equals(fileItem.getName())){
System.out.println("檔案大小:"+fileItem.getSize());
System.out.println("檔案型別:"+fileItem.getContentType());
System.out.println("檔名稱:"+fileItem.getName());
String rootPath = ctx.getRealPath("/");
System.out.println("專案根目錄:"+rootPath);
File tempFile = new File(rootPath+savePath,fileItem.getName());
//判斷父目錄是否存在,不存在就建立
mkdir(tempFile.getParentFile());
fileItem.write(tempFile);
request.setAttribute("uploadMsg", "上傳檔案成功!");
System.out.println("上傳成功!");
}else{
request.setAttribute("uploadMsg", "沒有選擇上傳檔案!");
System.out.println("沒有選擇上傳檔案!");
}
}
}
}catch(Exception e){
e.printStackTrace();
request.setAttribute("uploadMsg", "上傳檔案失敗!");
}
Attachment attachment = new Attachment();
attachment.setAttachName("測試2");
attachment.setAttachPath("F:\\CC.txt");
attachment.setAttachSize(20);
attachment.setAttachSuffix("txt");
attachment.setCreateDate(DateUtil.getCurrDateStr());
attachment.setId(IDGenerator.getUniqueID());
attachment.setUserId(IDGenerator.getUniqueID());
int count = attachmentService.save(attachment);
System.out.println("path:"+savePath);
System.out.println("count:"+count);
JSONObject jsonObj = new JSONObject();
jsonObj.put("code", "100");
jsonObj.put("msg", "上傳成功!");
System.out.println(jsonObj.toString());
response.getWriter().write(jsonObj.toString());
}
private void testURLDecoder(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
String testStr = StringUtil.trimStr(request.getParameter("testStr"));
System.out.println(testStr);
System.out.println(new String(testStr.getBytes("ISO8859_1"),"UTF-8"));
System.out.println(URLDecoder.decode(testStr, "ISO8859_1"));
System.out.println(URLDecoder.decode(testStr, "UTF-8"));
}
private void uploadAttach(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
JSONObject resultJson = new JSONObject();
try{
List<FileItem> fileItemList = upload.parseRequest(request);
Iterator<FileItem> fileItemIter = fileItemList.iterator();
while(fileItemIter.hasNext()){
FileItem fileItem = fileItemIter.next();
//判斷是否表單提交的引數
if(fileItem.isFormField()){
System.out.println("表單引數名:"+fileItem.getFieldName()+"屬性值:"+fileItem.getString("utf-8"));
}else{
if(!"".equals(fileItem.getName())){
System.out.println("檔案大小:"+fileItem.getSize());
System.out.println("檔案型別:"+fileItem.getContentType());
System.out.println("檔名稱:"+fileItem.getName());
//表單上傳的文件名稱
String pathName = fileItem.getName();
String fileFullName = FileUtil.getFileFullName(pathName);
String fileSimpleName = fileFullName;
if(!"".equals(FileUtil.getFileSimpleName(fileFullName))){
fileSimpleName = FileUtil.getFileSimpleName(fileFullName);
}
String rootPath = ctx.getRealPath("/");
String filePath = rootPath+savePath + File.separator + fileFullName;
System.out.println("檔案路徑:"+filePath);
File tempFile = new File(filePath);
Attachment attachment = new Attachment();
attachment.setId(IDGenerator.getUniqueID());
attachment.setAttachName(fileSimpleName);
attachment.setAttachSuffix(FileUtil.getFileSuffix(fileFullName));
attachment.setAttachPath(filePath);
attachment.setCreateDate(DateUtil.getCurrDateStr());
attachment.setUserId("10000");
attachment.setAttachSize((int)fileItem.getSize());
//判斷父目錄是否存在,不存在就建立
mkdir(tempFile.getParentFile());
fileItem.write(tempFile);
int resultCount = this.attachmentService.save(attachment);
if(resultCount > 0 ){
resultJson.put("errno", "0");
String portraitUrl = request.getContextPath()+"/uploadController?action=getImageFile&attachId="+attachment.getId();
try{
portraitUrl = URLEncoder.encode(portraitUrl,"UTF-8");
}catch(Exception e2){}
resultJson.put("picId", attachment.getId());
resultJson.put("portraitUrl", portraitUrl);
}else{
resultJson.put("errno", "5");
}
}
}
}
}catch(Exception e){
e.printStackTrace();
resultJson.put("errno", "4");
}
System.out.println(resultJson.toString());
renderHtml(response, resultJson.toString());
}
private void uploadAttachToJpg(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
JSONObject resultJson = new JSONObject();
try{
List<FileItem> fileItemList = upload.parseRequest(request);
Iterator<FileItem> fileItemIter = fileItemList.iterator();
while(fileItemIter.hasNext()){
FileItem fileItem = fileItemIter.next();
//判斷是否表單提交的引數
if(fileItem.isFormField()){
System.out.println("