利用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 相关文章推荐
javascript GUID生成器实现代码
Oct 31 Javascript
ExtJS PropertyGrid中使用Combobox选择值问题
Jun 13 Javascript
元素绑定click点击事件方法
Jun 08 Javascript
Bootstrap的图片轮播示例代码
Aug 31 Javascript
浅谈JavaScript 浏览器对象
Jun 03 Javascript
AngularJS入门教程之与服务器(Ajax)交互操作示例【附完整demo源码下载】
Nov 02 Javascript
JavaScript 字符串常用操作小结(非常实用)
Nov 30 Javascript
JS实现touch 点击滑动轮播实例代码
Jan 19 Javascript
Vue.js中轻松解决v-for执行出错的三个方案
Jun 09 Javascript
Bootstrap Table实现定时刷新数据的方法
Aug 13 Javascript
详解Vue项目中出现Loading chunk {n} failed问题的解决方法
Sep 14 Javascript
解决vue刷新页面以后丢失store的数据问题
Aug 11 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
php实现jQuery扩展函数
2009/10/30 PHP
PHP中for与foreach的区别分析
2011/03/09 PHP
php实现监听事件
2013/11/06 PHP
php编写的抽奖程序中奖概率算法
2015/05/14 PHP
Yii2框架实现注册和登录教程
2016/09/30 PHP
php使用 readfile() 函数设置文件大小大小的方法
2017/08/11 PHP
PHP生成随机码的思路与方法实例探索
2019/04/11 PHP
PHP进阶学习之反射基本概念与用法分析
2019/06/18 PHP
jQuery Ajax使用 全解析
2010/12/15 Javascript
Javascript实现滚动图片新闻的实例代码
2013/11/27 Javascript
JavaScript 学习笔记之基础中的基础
2015/01/13 Javascript
每天一篇javascript学习小结(RegExp对象)
2015/11/17 Javascript
快速将Vue项目升级到webpack3的方法步骤
2017/09/14 Javascript
jQuery实现table中两列CheckBox只能选中一个的示例
2017/09/22 jQuery
JavaScript异步加载问题总结
2018/02/17 Javascript
使用Vue制作图片轮播组件思路详解
2018/03/21 Javascript
微信小程序从注册账号到上架(图文详解)
2019/07/17 Javascript
layui table 表格上添加日期控件的两种方法
2019/09/28 Javascript
javascript实现超好看的3D烟花特效
2020/01/01 Javascript
从零开始用webpack构建一个vue3.0项目工程的实现
2020/09/24 Javascript
使用PyCharm配合部署Python的Django框架的配置纪实
2015/11/19 Python
Numpy数组转置的两种实现方法
2018/04/17 Python
Python+Pandas 获取数据库并加入DataFrame的实例
2018/07/25 Python
Python解析json代码实例解析
2019/11/25 Python
Python+Kepler.gl实现时间轮播地图过程解析
2020/07/20 Python
不同浏览器对CSS3和HTML5的支持状况
2009/10/31 HTML / CSS
使用CSS3实现input多选框自定义样式的方法示例
2019/07/19 HTML / CSS
俄罗斯旅游网站:Tripadvisor俄罗斯
2017/03/21 全球购物
几道数据库的面试题或笔试题
2014/05/31 面试题
Structs界面控制层技术
2013/10/11 面试题
个人自我鉴定写法
2013/11/30 职场文书
中国好声音华少广告词
2014/03/17 职场文书
政风行风评议个人心得体会
2014/10/29 职场文书
2015年高一班主任工作总结
2015/05/13 职场文书
建房合同协议书
2016/03/21 职场文书
vue实现可以快进后退的跑马灯组件
2022/04/08 Vue.js