使用imgareaselect 輔助後臺進行圖片裁剪
由於項目其中用到圖片裁剪,本來能夠不用到後臺進行裁剪的,可是要兼容萬惡的IE瀏覽器,所以不得不使用後臺進行裁剪。
這次使用到imgareaselect?插件獲取須要裁剪區域的坐標。再由後臺進行裁剪操作。
先上個效果圖再說
可是這裏有一個坑就是上傳的圖片過大,可能會造成裁剪的區域跟插件中顯示的不一樣,所以得如今後臺對雲圖片進行壓縮在裁剪
/** * 等比例壓縮算法: * 算法思想:依據壓縮基數和壓縮比來壓縮原圖,生產一張圖片效果最接近原圖的縮略圖 * @param srcURL 原圖地址 * @param deskURL 縮略圖地址 * @param comBase 壓縮基數 * @param scale 壓縮限制(寬/高)比例 一般用1: * 當scale>=1,縮略圖height=comBase,width按原圖寬高比例;若scale<1,縮略圖width=comBase,height按原圖寬高比例 * @throws Exception */ public static void saveMinPhoto(String srcURL, String deskURL, double comBase, double scale) throws Exception { File srcFile = new java.io.File(srcURL); String ext = srcURL.substring(srcURL.lastIndexOf(".") + 1); Image src = ImageIO.read(srcFile); int srcHeight = src.getHeight(null); int srcWidth = src.getWidth(null); int deskHeight = 0;// 縮略圖高 int deskWidth = 0;// 縮略圖寬 double srcScale = (double) srcHeight / srcWidth; /**縮略圖寬高算法*/ if ((double) srcHeight > comBase || (double) srcWidth > comBase) { if (srcScale >= scale || 1 / srcScale > scale) { if (srcScale >= scale) { deskHeight = (int) comBase; deskWidth = srcWidth * deskHeight / srcHeight; } else { deskWidth = (int) comBase; deskHeight = srcHeight * deskWidth / srcWidth; } } else { if ((double) srcHeight > comBase) { deskHeight = (int) comBase; deskWidth = srcWidth * deskHeight / srcHeight; } else { deskWidth = (int) comBase; deskHeight = srcHeight * deskWidth / srcWidth; } } } else { deskHeight = srcHeight; deskWidth = srcWidth; } BufferedImage tag = new BufferedImage(deskWidth, deskHeight, BufferedImage.TYPE_3BYTE_BGR); tag.getGraphics().drawImage(src, 0, 0, deskWidth, deskHeight, null); //繪制縮小後的圖 FileOutputStream deskImage = new FileOutputStream(deskURL); //輸出到文件流 ImageIO.write(tag, ext, new File(deskURL)); deskImage.close(); }
這就是壓縮之後在進行裁剪了。好了上完整代碼先
<!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> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>上傳頭像</title> <link rel="stylesheet" href="../../statics/css/ewt/style_1.css" type="text/css"> <link rel="stylesheet" href="../../statics/css/ewt/style_shangchuangtouxiang.css"> <link rel="stylesheet" type="text/css" href="../../statics/css/ewt/imgareaselect-default.css"> <link rel="stylesheet" href="../../statics/css/ewt/style.css" type="text/css" /> <link rel="stylesheet" href="../../statics/scripts/layer/skin/default/layer.css"> <script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script> <script src="../../statics/scripts/include.js"></script> <script src="../../statics/scripts/template.js"></script> <script src="../../statics/scripts/layer/layer.js"></script> <script src="../../statics/scripts/cropbox.js"></script> <script src="../../statics/scripts/jquery.imgareaselect.pack.js"></script> <script src="../../statics/scripts/ajaxfileupload.js"></script> <script src="../../ewt/user/scripts/shangchuangtouxiang.js"></script> <script src="../../ewt/common/config.js"></script> </head> <body> <include src="../common/user_head.html"></include> <div class="bggg"> <div class="box"> <div class="bos"> <include src="../common/user_menu.html"></include> <div class="bos_r"> <div class="biaoti"> <h3>上傳頭像</h3> </div> <div style=" width:915px; height: 400; display: block; overflow: hidden; margin: 30px auto; "> <div style=" width:430px; margin:0 auto;"> <div class="frame" style="margin: 0 0.3em; width: 300px; height: 300px; float: left;"> <img id="photo" src="" style="width: 300px; height: 300px;"/> </div> <div id="preview" style="width: 100px; height: 100px; overflow: hidden; float: left;"> <img src="" style="width: 100px; height: 100px;" id="smallImage"/> </div> </div> </div> <div style=" width:425px; margin:30px auto;"> <div class="input_XZ1"> <div class="input_XZ">選擇圖片</div> <input id="uplodimage" class="input_style" name="uplodimage" type="file" onchange="uplodImage(this)"> </div> <input id="imgUrl" type="hidden"> <input type="button" value="上傳" class="input_SC" onclick="upold();"> </div> <input type="hidden" id="x1" value="" /> <input type="hidden" id="y1" value="" /> <input type="hidden" id="x2" value="" /> <input type="hidden" id="y2" value="" /> <input type="hidden" id="w" value="" /> <input type="hidden" id="h" value="" /> </div> </div> </div> </div> <include src="../common/user_footer.html"></include> </body> </html>
js 代碼
function preview(img, selection) { if (!selection.width || !selection.height) return; var scaleX = 100 / selection.width; var scaleY = 100 / selection.height; $(‘#preview img‘).css({ width: Math.round(scaleX * 300), height: Math.round(scaleY * 300), marginLeft: -Math.round(scaleX * selection.x1), marginTop: -Math.round(scaleY * selection.y1) }); $(‘#x1‘).val(selection.x1); $(‘#y1‘).val(selection.y1); $(‘#x2‘).val(selection.x2); $(‘#y2‘).val(selection.y2); $(‘#w‘).val(selection.width); $(‘#h‘).val(selection.height); } $(function () { }); //上傳原始圖片 function uplodImage(target) { if(checkImage(target)){ var url = httpUtils.rootPath+‘/component/upload.do‘; $.ajaxFileUpload({ url: url, //用於文件上傳的服務器端請求地址 secureuri: false, //是否須要安全協議,一般設置為false fileElementId: ‘uplodimage‘, //文件上傳域的ID dataType: ‘json‘, //返回值類型 一般設置為json success: function (data) //服務器成功響應處理函數 { var filePath = data.filePath; $(‘#photo‘).attr(‘src‘,httpUtils.rootPath+‘/component/upload.do?action=download&filepath=‘+filePath); $(‘#smallImage‘).attr(‘src‘,httpUtils.rootPath+‘/component/upload.do?action=download&filepath=‘+filePath); $(‘#imgUrl‘).val(filePath); $(‘#photo‘).imgAreaSelect({ aspectRatio: ‘1:1‘, x1: 50, y1: 50, x2: 241, y2: 241, handles: true, fadeSpeed: 200, onSelectChange: preview }); $(‘#x1‘).val("50"); $(‘#y1‘).val("50"); $(‘#x2‘).val("241"); $(‘#y2‘).val("241"); $(‘#w‘).val("191"); $(‘#h‘).val("191"); } }); } } //上傳裁剪後的圖片 function upold() { if($(‘#imgUrl‘).val()==‘‘){ layer.alert("請先選擇圖片在上傳"); return false; } $.ajax({ type: "post", url:httpUtils.rootPath+‘/user/setHeadPicture‘, beforeSend: function(request) { request.setRequestHeader("jmtcp", header); }, async:false, data: { x:$(‘#x1‘).val(), y:$(‘#y1‘).val(), width: $(‘#w‘).val(), imgUrl : $(‘#imgUrl‘).val(), heigth: $(‘#h‘).val() }, dataType: "json", success: function(data){ if(data.code==1){ layer.alert(data.message,function(){ window.location.href = ‘../user/grzy.html‘; }); }else{ layer.alert(data.message); } } }); } function checkImage(target) { var isIE = /msie/i.test(navigator.userAgent) && !window.opera; var fileSize = 0; var filepath = target.value; // 為了避免轉義反斜杠出問題。這裏將對其進行轉換 var re = /(\+)/g; var filename = filepath.replace(re, "#"); // 對路徑字符串進行剪切截取 var one = filename.split("#"); // 獲取數組中最後一個,即文件名稱 var two = one[one.length - 1]; // 再對文件名稱進行截取,以取得後綴名 var three = two.split("."); // 獲取截取的最後一個字符串,即為後綴名 var last = three[three.length - 1]; // 加入須要推斷的後綴名類型 var tp = "jpg,gif,bmp,JPG,GIF,BMP,png"; // 返回符合條件的後綴名在字符串中的位置 var rs = tp.indexOf(last); // 假設返回的結果大於或等於0。說明包括同意上傳的文件類型 if(rs < 0){ layer.alert(‘您選擇的上傳文件不是有效的圖片文件‘); return false; } // if (isIE && !target.files) { // IE瀏覽器 // var filePath = target.value; // 獲得上傳文件的絕對路徑 // var fileSystem = new ActiveXObject("Scripting.FileSystemObject"); // // GetFile(path) 方法從磁盤獲取一個文件並返回。 // var file = fileSystem.GetFile(filePath); // fileSize = file.Size; // 文件大小。單位:b // } // else { // 非IE瀏覽器 // fileSize = target.files[0].size; // } var img1 = document.getElementById(‘photo‘); //img1.dynsrc=target.value; //img1.fileSize:IE , fileObj.files[0].fileSize:chrome, fileObj.files[0].size:FF var fileSize = img1.fileSize || target.files[0].fileSize || target.files[0].size; var size = fileSize / 1024 / 1024; if (size > 5) { layer.alert("圖片不能大於5M"); return false; } return true; }
後臺代碼
public class CutImageUtils { public static SecureRandom rnd = new SecureRandom(); public static String cutImage(int x, int y, int width, int height,String srcPath) throws Exception{ String root = ApplicationContext.getProperty("upload_folder"); String imagePath = root+srcPath; FileInputStream is = null; ImageInputStream iis = null; String uploadFolder = null ; String filepath = null ; String serverName = null ; uploadFolder = ApplicationContext.getProperties().getProperty("upload_folder").toString() ; filepath = generateServerFolder() ; serverName = generateServerName(srcPath) ; File file = new File(uploadFolder + filepath); if (!file.exists()) { file.mkdirs(); } try { // 讀取圖片文件 saveMinPhoto(imagePath, imagePath, 300, 0.9d); //resetsize(imagePath, imagePath); is = new FileInputStream(imagePath); String ext = srcPath.substring(srcPath.lastIndexOf(".") + 1); Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName(ext); ImageReader reader = it.next(); // 獲取圖片流 iis = ImageIO.createImageInputStream(is); reader.setInput(iis, true); ImageReadParam param = reader.getDefaultReadParam(); /** * * 圖片裁剪區域。Rectangle 指定了坐標空間中的一個區域。通過 Rectangle 對象 * * 的左上頂點的坐標(x,y)、寬度和高度能夠定義這個區域。*/ Rectangle rect = new Rectangle(x, y, width, height); // 提供一個 BufferedImage。將其用作解碼像素數據的目標。 param.setSourceRegion(rect); BufferedImage bi = reader.read(0, param); // 保存新圖片 ImageIO.write(bi, ext, new File(uploadFolder + filepath + serverName)); } catch (FileNotFoundException e) { // TODO Auto-generated catch block if (is != null) is.close(); if (iis != null) iis.close(); e.printStackTrace(); } return filepath + serverName ; } /** * * @param config * @param file * @param request * @return */ public static String generateServerName(String clientPath) { //按當前時間的分鐘毫秒+3位隨機數 Calendar c = Calendar.getInstance(); String min = get(c,Calendar.MINUTE); String sec = get(c,Calendar.SECOND); String mis = get(c,Calendar.MILLISECOND); String rnd = random(); String ext = getFileExt(getClientName(clientPath)); return min + sec + mis + rnd + ext ; } /** 客戶端文件名稱 */ public static String getClientName(String clientPath) { if(null != clientPath){ int index1 = clientPath.lastIndexOf("/"); int index2 = clientPath.lastIndexOf("\\"); if(index2 > index1){ index1 = index2; } return clientPath.substring(index1+1,clientPath.length()); } return null; } public static String getFileExt(String fileName){ if(null != fileName){ int dot = fileName.lastIndexOf("."); if(dot >= 0){ return fileName.substring(dot); } } return ""; } public static String random(){ String value = String.valueOf(rnd.nextInt(1000)); if(value.length() < 3){ for(int i=value.length();i<3;i++){ value = "0" + value; } } return value; } public static String generateServerFolder() { //按當前年月日和小時生成文件路徑 Calendar c = Calendar.getInstance(); String year = get(c,Calendar.YEAR); String mon = get(c,Calendar.MONTH); String day = get(c,Calendar.DAY_OF_MONTH); String hour = get(c,Calendar.HOUR_OF_DAY); return year + "/" + mon + "/" + day + "/" + hour + "/"; } public static String get(Calendar c,int field){ int v = c.get(field); if(field == Calendar.MONTH){ v += 1; } String value = String.valueOf(v); if(value.length() == 1){ value = "0" + value; } return value; } /** * 縮小圖片到固定長高 * @param srcImagePath 讀取圖片路徑 * @param toImagePath 寫入圖片路徑 * @param width 縮小後圖片寬度 * @param height 縮小後圖片長度 * @throws IOException */ public static void reduceImageByWidthHeight(String srcImagePath, String toImagePath, int width, int height) throws IOException{ FileOutputStream out = null; try{ //讀入文件 File file = new File(srcImagePath); String ext = srcImagePath.substring(srcImagePath.lastIndexOf(".") + 1); // 構造Image對象 BufferedImage src = javax.imageio.ImageIO.read(file); // 縮小邊長 BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 繪制縮小後的圖片 tag.getGraphics().drawImage(src, 0, 0, width, height, null); out = new FileOutputStream(toImagePath); ImageIO.write(tag, ext, new File(toImagePath)); }catch(Exception e){ e.printStackTrace(); }finally{ if(out != null){ out.close(); } out = null; System.gc(); } } /** * 等比例壓縮算法: * 算法思想:依據壓縮基數和壓縮比來壓縮原圖。生產一張圖片效果最接近原圖的縮略圖 * @param srcURL 原圖地址 * @param deskURL 縮略圖地址 * @param comBase 壓縮基數 * @param scale 壓縮限制(寬/高)比例 一般用1: * 當scale>=1,縮略圖height=comBase,width按原圖寬高比例;若scale<1,縮略圖width=comBase,height按原圖寬高比例 * @throws Exception */ public static void saveMinPhoto(String srcURL, String deskURL, double comBase, double scale) throws Exception { File srcFile = new java.io.File(srcURL); String ext = srcURL.substring(srcURL.lastIndexOf(".") + 1); Image src = ImageIO.read(srcFile); int srcHeight = src.getHeight(null); int srcWidth = src.getWidth(null); int deskHeight = 0;// 縮略圖高 int deskWidth = 0;// 縮略圖寬 double srcScale = (double) srcHeight / srcWidth; /**縮略圖寬高算法*/ if ((double) srcHeight > comBase || (double) srcWidth > comBase) { if (srcScale >= scale || 1 / srcScale > scale) { if (srcScale >= scale) { deskHeight = (int) comBase; deskWidth = srcWidth * deskHeight / srcHeight; } else { deskWidth = (int) comBase; deskHeight = srcHeight * deskWidth / srcWidth; } } else { if ((double) srcHeight > comBase) { deskHeight = (int) comBase; deskWidth = srcWidth * deskHeight / srcHeight; } else { deskWidth = (int) comBase; deskHeight = srcHeight * deskWidth / srcWidth; } } } else { deskHeight = srcHeight; deskWidth = srcWidth; } BufferedImage tag = new BufferedImage(deskWidth, deskHeight, BufferedImage.TYPE_3BYTE_BGR); tag.getGraphics().drawImage(src, 0, 0, deskWidth, deskHeight, null); //繪制縮小後的圖 FileOutputStream deskImage = new FileOutputStream(deskURL); //輸出到文件流 ImageIO.write(tag, ext, new File(deskURL)); deskImage.close(); } public static void main(String[] args) { try { String src = CutImageUtils.cutImage(11, 12, 100, 100, "2017/01/04/17/6348162d-5b50-4e7d-b414-93140498f8de.jpg"); System.out.println(src); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
使用imgareaselect 輔助後臺進行圖片裁剪