利用imgareaselect辅助后台实现图片上传裁剪


Posted in Javascript onMarch 02, 2017

因为项目当中用到图片裁剪,本来可以不用到后台进行裁剪的,但是要兼容万恶的IE浏览器,所以不得不使用后台进行裁剪。

这次使用到imgareaselect 插件获取需要裁剪区域的坐标,再由后台进行裁剪操作。先上个效果图再说

利用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> 
<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(); 
    } 
  } 
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery .tmpl(), .template()学习资料小结
Jul 18 Javascript
JQuery防止退格键网页后退的实现代码
Mar 23 Javascript
js日期、星座的级联显示代码
Jan 23 Javascript
js中文逗号转英文实现
Feb 11 Javascript
Firefox下无法正常显示年份的解决方法
Sep 04 Javascript
jquery实现表单验证简单实例演示
Nov 23 Javascript
jQuery实现select模糊查询(反射机制)
Jan 14 Javascript
JavaScript中transform实现数字翻页效果
Mar 08 Javascript
又一款MVVM组件 构建自己的Vue组件(2)
Mar 13 Javascript
用vue写一个仿简书的轮播图的示例代码
Mar 13 Javascript
layui点击按钮页面会自动刷新的解决方案
Oct 25 Javascript
JS错误处理与调试操作实例分析
Apr 13 Javascript
详谈jQuery Ajax(load,post,get,ajax)的用法
Mar 02 #Javascript
Bootstrap入门教程一Hello Bootstrap初识
Mar 02 #Javascript
详解使用grunt完成requirejs的合并压缩和js文件的版本控制
Mar 02 #Javascript
jQuery上传多张图片带进度条样式(DEMO)
Mar 02 #Javascript
jquery仿京东侧边栏导航效果
Mar 02 #Javascript
关于jQuery EasyUI 中刷新Tab选项卡后一个页面变形的解决方法
Mar 02 #Javascript
JavaScript html5利用FileReader实现上传功能
Mar 27 #Javascript
You might like
第十节--抽象方法和抽象类
2006/11/16 PHP
Mysql中分页查询的两个解决方法比较
2013/05/02 PHP
HTTP状态代码以及定义(解释)
2007/02/02 Javascript
javascript 学习之旅 (1)
2009/02/05 Javascript
javascript 鼠标滚轮事件
2009/04/09 Javascript
自定义右键属性覆盖浏览器默认右键行为实现代码
2013/02/02 Javascript
制作jquery遮罩层效果导航菜单代码分享
2013/12/25 Javascript
对之前写的jquery分页做下升级
2014/06/19 Javascript
JavaScript学习笔记之基础语法
2015/01/22 Javascript
使用jQuery实现input数值增量和减量的方法
2015/01/24 Javascript
JS实现光滑展开合拢的菜单效果代码
2015/09/16 Javascript
Node.js重新刷新session过期时间的方法
2016/02/04 Javascript
Js与Jq获取浏览器和对象值的方法
2016/03/18 Javascript
AngularJS实现根据变量改变动态加载模板的方法
2016/11/04 Javascript
微信小程序 图片绝对定位(背景图片)
2017/04/05 Javascript
jQuery遍历节点方法汇总(推荐)
2017/05/13 jQuery
React Native之ListView实现九宫格效果的示例
2017/08/02 Javascript
解决vue.js 数据渲染成功仍报错的问题
2018/08/25 Javascript
详解create-react-app 2.0版本如何启用装饰器语法
2018/10/23 Javascript
Vue CL3 配置路径别名详解
2019/05/30 Javascript
js实现点击上传图片并设为模糊背景
2020/08/02 Javascript
[28:28]Ti4 冒泡赛第二天NEWBEE vs NaVi 2
2014/07/15 DOTA
python命令行参数sys.argv使用示例
2014/01/28 Python
Python实现桶排序与快速排序算法结合应用示例
2017/11/22 Python
详解Python可视化神器Yellowbrick使用
2019/11/11 Python
Python 输出详细的异常信息(traceback)方式
2020/04/08 Python
Python Web项目Cherrypy使用方法镜像
2020/11/05 Python
Python导入父文件夹中模块并读取当前文件夹内的资源
2020/11/19 Python
Python离线安装各种库及pip的方法
2020/11/28 Python
关于Assembly命名空间的三个面试题
2015/07/23 面试题
市场营销专业应届生自荐信
2014/06/19 职场文书
人事主管岗位职责
2015/02/04 职场文书
转变工作作风心得体会
2016/01/23 职场文书
Go语言中break label与goto label的区别
2021/04/28 Golang
Win11怎么添加用户?Win11添加用户账户的方法
2022/07/15 数码科技
maven 解包依赖项中的文件的解决方法
2022/07/15 Java/Android