利用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 相关文章推荐
js实现权限树的更新权限时的全选全消功能
Feb 17 Javascript
Javascript 汉字字节判断
Aug 01 Javascript
JavaScript中常见陷阱小结
Apr 27 Javascript
浅谈javascript的数据类型检测
Jul 10 Javascript
自己动手制作jquery插件之自动添加删除行的实现
Oct 13 Javascript
Javascript和Java获取各种form表单信息的简单实例
Feb 14 Javascript
JavaScript实现拖拽网页内元素的方法
Apr 15 Javascript
jQuery ajaxSubmit 实现ajax提交表单局部刷新
Jul 04 Javascript
js设置和获取自定义属性的方法
Oct 20 Javascript
微信小程序实现搜索指定景点周边美食、酒店
May 18 Javascript
JavaScript中while循环的基础使用教程
Aug 11 Javascript
Vue自定义铃声提示音组件的实现
Jan 22 Vue.js
详谈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/02 无线电
PHP+Ajax实现无刷新分页实例详解(附demo源码下载)
2016/04/07 PHP
jQuery TextBox自动完成条
2009/07/22 Javascript
自己的js工具_Form 封装
2009/08/21 Javascript
JS模拟面向对象全解(二、类型与赋值)
2011/07/13 Javascript
THREE.JS入门教程(3)着色器-下
2013/01/24 Javascript
js 图片随机不定向浮动的实现代码
2013/07/02 Javascript
javascript数组操作总结和属性、方法介绍
2014/04/05 Javascript
jquery操作checkbox实现全选和取消全选
2014/05/02 Javascript
每天一篇javascript学习小结(RegExp对象)
2015/11/17 Javascript
javascript实现数组去重的多种方法
2016/03/14 Javascript
jQuery实现无限往下滚动效果代码
2016/04/16 Javascript
AngularJS实现controller控制器间共享数据的方法示例
2017/10/30 Javascript
React Native 自定义下拉刷新上拉加载的列表的示例
2018/03/01 Javascript
JavaScript实现微信红包算法及问题解决方法
2018/04/26 Javascript
js根据json数据中的某一个属性来给数据分组的方法
2018/10/08 Javascript
jQuery实现移动端扭蛋机抽奖
2020/11/08 jQuery
[00:20]TI9不朽观赛名额抽取
2019/08/05 DOTA
[01:37]PWL S2开团时刻DAY1&2——这符有毒
2020/11/20 DOTA
Python多线程编程(七):使用Condition实现复杂同步
2015/04/05 Python
python检查URL是否正常访问的小技巧
2017/02/25 Python
python在非root权限下的安装方法
2018/01/23 Python
解决python通过cx_Oracle模块连接Oracle乱码的问题
2018/10/18 Python
Python定时发送消息的脚本:每天跟你女朋友说晚安
2018/10/21 Python
使用pip安装python库的多种方式
2019/07/31 Python
Python中正反斜杠(‘/’和‘\’)的意义与用法
2019/08/12 Python
python 正则表达式参数替换实例详解
2020/01/17 Python
Microsoft新加坡官方网站:购买微软最新软件和技术产品
2016/10/28 全球购物
伦敦剧院门票:From The Box Office
2018/06/30 全球购物
医学院护理专业应届生求职信
2013/11/12 职场文书
常务副县长“四风”个人对照检查材料思想汇报
2014/10/02 职场文书
2014年电工工作总结
2014/11/20 职场文书
vue实现无缝轮播效果(跑马灯)
2021/05/14 Vue.js
vue点击弹窗自动触发点击事件的解决办法(模拟场景)
2021/05/25 Vue.js
Windows安装Anaconda3的方法及使用过程详解
2021/06/11 Python
Python中的datetime包与time包包和模块详情
2022/02/28 Python