利用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为textarea添加maxlength属性的代码
Apr 07 Javascript
DOM_window对象属性之--clipboardData对象操作代码
Feb 03 Javascript
JavaScript高级程序设计(第3版)学习笔记4 js运算符和操作符
Oct 11 Javascript
JS 实现导航栏悬停效果(续)
Sep 24 Javascript
Flow之一个新的Javascript静态类型检查器
Dec 21 Javascript
js Canvas绘制圆形时钟效果
Feb 17 Javascript
angular4自定义组件详解
Sep 28 Javascript
vue watch监听对象及对应值的变化详解
Feb 24 Javascript
vue鼠标移入添加class样式,鼠标移出去除样式(active)实现方法
Aug 22 Javascript
mongodb初始化并使用node.js实现mongodb操作封装方法
Apr 02 Javascript
使用异步controller与jQuery实现卷帘式分页
Jun 18 jQuery
vue 判断两个时间插件结束时间必选大于开始时间的代码
Nov 04 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
咖啡常见的种类
2021/03/03 新手入门
简单示例AJAX结合PHP代码实现登录效果代码
2008/07/25 PHP
PHP中的多种加密技术及代码示例解析
2016/10/20 PHP
PHP自定义函数获取汉字首字母的方法
2016/12/01 PHP
深入聊聊Array的sort方法的使用技巧.详细点评protype.js中的sortBy方法
2007/04/12 Javascript
IE6下CSS图片缓存问题解决方法
2010/12/09 Javascript
原生javascript图片自动或手动切换示例附演示源码
2013/09/04 Javascript
js获取所有checkbox的值的简单实例
2016/05/30 Javascript
javascript数组定义的几种方法
2017/10/06 Javascript
vue页面跳转后返回原页面初始位置方法
2018/02/11 Javascript
解决vue的 v-for 循环中图片加载路径问题
2018/09/03 Javascript
vue子组件改变父组件传递的prop值通过sync实现数据双向绑定(DEMO)
2020/02/01 Javascript
JS call()及apply()方法使用实例汇总
2020/07/11 Javascript
详解template标签用法(含vue中的用法总结)
2021/01/12 Vue.js
[05:46]DOTA2英雄梦之声_第18期_陈
2014/06/20 DOTA
Python-基础-入门 简介
2014/08/09 Python
浅析python中SQLAlchemy排序的一个坑
2017/02/24 Python
python的dataframe和matrix的互换方法
2018/04/11 Python
Python之pandas读写文件乱码的解决方法
2018/04/20 Python
儿童学习python的一些小技巧
2018/05/27 Python
Python 查看list中是否含有某元素的方法
2018/06/27 Python
python3.6生成器yield用法实例分析
2019/08/23 Python
django商品分类及商品数据建模实例详解
2020/01/03 Python
Python3之外部文件调用Django程序操作model等文件实现方式
2020/04/07 Python
法国体育用品商店:GO Sport
2019/10/23 全球购物
医学院毕业生自荐信范文
2014/03/06 职场文书
品牌宣传方案
2014/03/21 职场文书
煤矿安全生产月活动总结
2014/07/05 职场文书
甘南现象心得体会
2014/09/11 职场文书
机电专业毕业生自我鉴定2014
2014/10/04 职场文书
小学老师对学生的评语
2014/12/29 职场文书
贷款担保书
2015/01/20 职场文书
公司员工体检通知
2015/04/21 职场文书
2015小学教师年度工作总结
2015/05/12 职场文书
2016年领导干部廉政承诺书
2016/03/24 职场文书
http通过StreamingHttpResponse完成连续的数据传输长链接方式
2022/02/12 Python