Home > Article > Web Front-end > imgareaselect auxiliary background implementation of image upload and cropping method tutorial
本文主要为大家详细介绍了利用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" rel="external nofollow" type="text/css"> <link rel="stylesheet" href="../../statics/css/ewt/style_shangchuangtouxiang.css" rel="external nofollow" > <link rel="stylesheet" type="text/css" href="../../statics/css/ewt/imgareaselect-default.css" rel="external nofollow" > <link rel="stylesheet" href="../../statics/css/ewt/style.css" rel="external nofollow" type="text/css" /> <link rel="stylesheet" href="../../statics/scripts/layer/skin/default/layer.css" rel="external nofollow" > <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> <p class="bggg"> <p class="box"> <p class="bos"> <include src="../common/user_menu.html"></include> <p class="bos_r"> <p class="biaoti"> <h3>上传头像</h3> </p> <p style=" width:915px; height: 400; display: block; overflow: hidden; margin: 30px auto; "> <p style=" width:430px; margin:0 auto;"> <p class="frame" style="margin: 0 0.3em; width: 300px; height: 300px; float: left;"> <img id="photo" src="" style="width: 300px; height: 300px;"/> </p> <p id="preview" style="width: 100px; height: 100px; overflow: hidden; float: left;"> <img src="" style="width: 100px; height: 100px;" id="smallImage"/> </p> </p> </p> <p style=" width:425px; margin:30px auto;"> <p class="input_XZ1"> <p class="input_XZ">选择图片</p> <input id="uplodimage" class="input_style" name="uplodimage" type="file" onchange="uplodImage(this)"> </p> <input id="imgUrl" type="hidden"> <input type="button" value="上传" class="input_SC" onclick="upold();"> </p> <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="" /> </p> </p> </p> </p> <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(); } } }
相关推荐:
The above is the detailed content of imgareaselect auxiliary background implementation of image upload and cropping method tutorial. For more information, please follow other related articles on the PHP Chinese website!