cropper本地预览 裁剪,上传到服务器

坑爹啊, 搞了2天,主要是昨天一直在搞 jcrop,这玩意不能缩放图片。 

如果容器定为600px ,从本地选一张大于600px的图片,那么到容器里会压缩, scrop获取不到图片的真实位置,导致上传到后台后,后台裁剪的图片不对


今天重新用cropper搞,终于搞好了。

  步骤:

    1  通过 本地 选择图片,预览,通过 选取框,选取一个正方形区域(可以设置大小和形状)

     2 本地获取 左顶点坐标(x,y), 和宽度 高度 4个参数

     3 然后通过 form表单提交到后台 即可

     4 后台 先把源文件存放,然后通过一个工具类 把源文件根据这4个参数 裁剪,生成一张图片, 

     5 我这里是通过 jquery form。js 提交 ,根据后台返回的json 关闭弹出框,并且把头像 src改为新设置的


效果:


cropper本地预览 裁剪,上传到服务器_第1张图片



前端 源代码:


  <pre>

   

<%@page import="org.w3c.dom.Document"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>




<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";

 
%>












<!DOCTYPE html>
<html>
<head>


<meta charset="UTF-8">


<base href="<%=basePath%>">




   <!--   bootstrap 样式  默认需要-->
  <link rel="stylesheet" href="components/FontAwesome4.4/css/font-awesome.min.css">
  <link rel="stylesheet" href="components/bootstrap/css/bootstrap.min.css">
  <link rel="stylesheet" href="components/cropper/dist/cropper.css">
 


     <!-- 首页左侧 折叠菜单 -->
 <link rel="stylesheet" href="css/main_leftmenu01.css">
 
   <!-- 设置头像弹出框 -->
  <link rel="stylesheet" href="css/cutUserFace.css">
  


   <!-- jquery和bootstrap 默认都需要 -->
<script src="js/jquery.min.js"></script>
<script src="components/bootstrap/js/bootstrap.min.js"></script>
 
  <script src="components/cropper/dist/cropper.js"></script>
  


     <!-- 首页左侧 折叠菜单 -->
     
<script src="js/main_leftmenu01.js"></script>


 <script src="js/jquery-form.js"></script> 
 <script src="components/layer2/layer/layer.js"></script>  
 




<script language="JavaScript"> 


 /* 跳出iframe */
   if (window != top) 
  
  {
         top.location.href = location.href; 
 
         //parent.location.reload();   
  
   }
 
 
 
 
</script>








  
  






<!-- <script src="components/layer2/layer/layer.js"></script> -->
 
<style type="text/css">




body {
margin: 0;
padding: 0;
border: 0;
height: 100%;
max-height: 100%;
}


a {
color:#ffffff;
}


a:visited {
 color:#ffffff;
text-decoration: none;
}


a:active {
  color:#ffffff;
text-decoration: none;
}
/* hover一定要放在最后面*/
a:hover {
 color:#ffffff;
text-decoration: none;
}






/*    主界面 top */
#toptitle {
position: absolute;
top: 0;
left: 0;
height: 100px;
color: #ffffff;
width: 100%;
overflow: hidden;
vertical-align: middle;
background-color: #317eb4;
}




 /* 左边菜单 */
#leftmenu {
position: fixed;
top: 100px;
left: 0;
height: 100%;
width: 180px;
overflow: auto;
vertical-align: top;
background-color: #585858;
}


/*  右边内容iframe容器 */
#maincontent {
position: fixed;
left: 180px;
top: 100px;
right: 0;
bottom: 0;
height: 100%;
overflow: auto;
background: #fff;
/* border-top: solid 1px #ea1718;
            border-left: solid 1px #ea1718;*/
}


 
</style>






<script type="text/javascript" language="javascript">


     //自动测算内容区域的高度
function iFrameHeight() {
var ifm = document.getElementById("content");
var subWeb = document.frames ? document.frames["content"].document: ifm.contentDocument;
if (ifm != null && subWeb != null) {
 

ifm.height = subWeb.body.scrollHeight;

if(ifm.height<640)
{
 ifm.height=640;
}

//ifm.width = subWeb.body.scrollWidth; 这个不能用,用的话,每点一次左边的连接,右边内容宽度会增加一些
}
}
</script>


</head>
<body  id="mainbody">


 
<div id="leftmenu">


<div class="leftsidebar_box">

<div class="line"></div>

<c:forEach var="superMenu"  items="${rightsList}">
 
   
       <dl>
           <dt style="background-image: url(${superMenu.tRightTypes.icopath})">
         ${superMenu.tRightTypes.name }<img src="components/menu01/images/left/select_xl01.png">
      </dt>
  
        <c:forEach var="secMenu"  items="${superMenu.rights }" >
                <dd>
                       <a href="${secMenu.url }"  target="content">${secMenu.name }</a>
                </dd>
         
          </c:forEach>
       
       </dl>

</c:forEach>
 


</div>


</div>




<div id="toptitle">

<%--  <div style="position: absolute;top: 10px;left: 20px;text-align: center">
       <img src="images/a8.jpg" style="width: 64px;height:64px;border-radius: 50%">
       <div><a href="javascript:void(0)"  id="openBtn">${username }</a></div>


         </div> --%>


<div style="text-align: center;">


<h1 style="color: #ffffff">恒金所理财业务管理系统</h1>
</div>

<div  style="position: absolute;top: 10px;right: 20px;text-align: center">
<div  style="float:right; ;font-size:18px;line-height:89px">
 
     <a href="manager/loginout.html" style="margin-left:20px"> 退 出</a>
</div>

<div  style="float:right;margin-right:10px;font-size:18px">
   <a href="javascript:void(0)"  id="openBtn">
           <c:choose>
              <c:when test="${ not empty user.pic }">
                        <img src="/userFacePic/${user.pic }" style="width: 64px;height:64px;border-radius: 50%" id="userImage">
              </c:when>
               <c:otherwise>
                        <img src="images/a8.jpg" style="width: 64px;height:64px;border-radius: 50%" id="userImage">
               </c:otherwise>
           
           </c:choose>
     
              <div style="font-size:12px">${user.realname }</div>
              </a>
</div>
 
</div>





</div>




<div id="maincontent">


  <iframe id="content" name="content"  onLoad="iFrameHeight()"
frameborder="0" scrolling="no" marginheight="0" marginwidth="0"
width="100%"  src="manager/defaultPage.html"></iframe>  
 
     <!--      刷新首页的时候 ,子页面路径保留 -->
<%--    <c:choose>
   
 
          <c:when test="${ not empty nowUrl }">    
            <iframe id="content" name="content"   height="99%" frameborder="0" scrolling="no" marginheight="0" marginwidth="0"  width="100%"  src="${nowUrl}"></iframe>
       </c:when>
         <c:otherwise>
            <iframe id="content" name="content"   height="99%" frameborder="0" scrolling="no" marginheight="0" marginwidth="0"  width="100%"  src="manager/defaultPage.html"></iframe>
         </c:otherwise>
   </c:choose> --%>

 


</div>

 






<!-- Modal -->
<div class="modal fade" id="cutPicDialog" >
  <div class="modal-dialog" role="document" style="width: 1280px;">


    <div class="modal-content">


      <div class="modal-header">
             头像裁剪
      </div>




      <div class="modal-body">






        <div class="container" style="margin-top: 40px; "   >


          <form  id="userFaceForm"   enctype="multipart/form-data">


                  <input type="hidden" id="userId"  name="userId" value="${user.id }">


            <div class="row">




              <div class="col-md-8"style="border: 1px solid #aaaaaa;border-radius: 4px;padding: 0px" >


                <div class="img-container" >


                  <img id="image" src="images/pic_default.png" alt="选择图片">
                </div>
              </div>


              <div class="col-md-3" style="border: 1px solid #aaaaaa;border-radius: 4px;margin-left: 30px">


                <div class="docs-preview clearfix">
                  <div class="img-preview preview-lg"></div>
                  <div class="img-preview preview-md"></div>
                  <div class="img-preview preview-sm"></div>
                  <div class="img-preview preview-xs"></div>
                </div>


                <!-- <h3 class="page-header">Data:</h3> -->
                <div class="docs-data">
                  <div class="input-group input-group-sm">
                    <label class="input-group-addon" for="dataX">左X</label>
                    <input type="text" class="form-control" id="dataX"   name="dataX" placeholder="x">
                    <span class="input-group-addon">px</span>
                  </div>
                  <div class="input-group input-group-sm">
                    <label class="input-group-addon" for="dataY">左Y</label>
                    <input type="text" class="form-control" id="dataY"     name="dataY"   placeholder="y">
                    <span class="input-group-addon">px</span>
                  </div>
                  <div class="input-group input-group-sm">
                    <label class="input-group-addon" for="dataWidth">宽度</label>
                    <input type="text" class="form-control" id="dataWidth"   name="dataWidth"  placeholder="width">
                    <span class="input-group-addon">px</span>
                  </div>
                  <div class="input-group input-group-sm">
                    <label class="input-group-addon" for="dataHeight">高度</label>
                    <input type="text" class="form-control" id="dataHeight"        name="dataHeight"         placeholder="height">
                    <span class="input-group-addon">px</span>
                  </div>
                  <!--  <div class="input-group input-group-sm">
                      <label class="input-group-addon" for="dataRotate">旋转</label>
                      <input type="text" class="form-control" id="dataRotate" placeholder="rotate">
                      <span class="input-group-addon">deg</span>
                    </div>-->


                </div>




                <!--开始 选择  缩放 提交 按钮-->
                <div class=" docs-buttons" style="margin-top: 20px">


                  <div class="btn-group" style="float: left">


                    <label class="btn btn-danger btn-upload " for="inputImage" title="选择图片" style="width:100px">
                      <input type="file" class="sr-only"    id="inputImage"   name="inputImage"    accept="image/*"   >
                       <span class="docs-tooltip" data-toggle="tooltip" title="选择图片">
                          <span class="fa fa-file-photo-o "></span>&nbsp;选图片 </span>
                    </label>
                  </div>




                  <div class="btn-group" style="float: left; ">


                    <button type="button" class="btn btn-primary" data-method="zoom" data-option="0.1" title="Zoom In">
            <span class="docs-tooltip" data-toggle="tooltip" title="放大图片">
              <span class="fa fa-search-plus"></span>
            </span>
                    </button>


                    <button type="button" class="btn btn-primary" data-method="zoom" data-option="-0.1" title="Zoom Out">
            <span class="docs-tooltip" data-toggle="tooltip" title="缩小图片">
              <span class="fa fa-search-minus"></span>
            </span>
                    </button>


                  </div>   <!-- 选择  缩放 提交 按钮 结束 -->
 
 
  <div style="clear: both"> </div>




                    <div class="btn-group" style="float: left">




                      <button type="button" class="btn btn-default" data-dismiss="modal"  style="    width: 100px;">


                        <span class="fa fa-close"></span>取消 </span>
                      </button>


                    </div>




                    <div class="btn-group" style="float: left">
                      <button type="submit" class="btn btn-primary"  style="  width: 100px;">


                        <span class="fa fa-check"></span>提交
                        </span>
                      </button>




                    </div>
                    
                    
                   </div>   <!--  doc butons -->
                </div>
             




              </div>




            </div>




          </form>






        </div>


        <!-- 莫泰框boty大结束-->
     </div>


   <!--    <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
        <button type="submit" class="btn btn-primary"  id="subBtn">提交</button>
      </div> -->




  </div>
 
</div>
 
<script>


    $(function () {
      'use strict';
      var console = window.console || { log: function () {} };
      var $image = $('#image');


      var $dataX = $('#dataX');
      var $dataY = $('#dataY');
      var $dataHeight = $('#dataHeight');
      var $dataWidth = $('#dataWidth');
      var $dataRotate = $('#dataRotate');
      var $dataScaleX = $('#dataScaleX');
      var $dataScaleY = $('#dataScaleY');
      var options = {
         //选框区域  1:1
        aspectRatio: 1 / 1,


         //预览区域
        preview: '.img-preview',
        crop: function (e) {
          $dataX.val(Math.round(e.x));
          $dataY.val(Math.round(e.y));
          $dataHeight.val(Math.round(e.height));
          $dataWidth.val(Math.round(e.width));
          $dataRotate.val(e.rotate);
          $dataScaleX.val(e.scaleX);
          $dataScaleY.val(e.scaleY);
        }
      };






      // Tooltip
      $('[data-toggle="tooltip"]').tooltip();




      // 响应 选框 事件
      $image.on({
        'build.cropper': function (e) {
          console.log(e.type);
        },
        'built.cropper': function (e) {
          console.log(e.type);
        },
        'cropstart.cropper': function (e) {
          console.log(e.type, e.action);
        },
        'cropmove.cropper': function (e) {
          console.log(e.type, e.action);
        },
        'cropend.cropper': function (e) {
          console.log(e.type, e.action);
        },
        'crop.cropper': function (e) {
          console.log(e.type, e.x, e.y, e.width, e.height, e.rotate, e.scaleX, e.scaleY);
        },
        'zoom.cropper': function (e) {
          console.log(e.type, e.ratio);
        }
      }).cropper(options);


















      // 放大 缩小事件  2个按钮上 增加了 data-method="zoom" 属性
      $('.docs-buttons').on('click', '[data-method]', function () {
        var $this = $(this);
        var data = $this.data();
        var $target;
        var result;


        if ($this.prop('disabled') || $this.hasClass('disabled')) {
          return;
        }


        if ($image.data('cropper') && data.method) {
          data = $.extend({}, data); // Clone a new one


          if (typeof data.target !== 'undefined') {
            $target = $(data.target);


            if (typeof data.option === 'undefined') {
              try {
                data.option = JSON.parse($target.val());
              } catch (e) {
                console.log(e.message);
              }
            }
          }


          result = $image.cropper(data.method, data.option, data.secondOption);


          switch (data.method) {
            case 'scaleX':
            case 'scaleY':
              $(this).data('option', -data.option);
              break;


            case 'getCroppedCanvas':
              if (result) {


                // Bootstrap's Modal
                $('#getCroppedCanvasModal').modal().find('.modal-body').html(result);


                if (!$download.hasClass('disabled')) {
                  $download.attr('href', result.toDataURL());
                }
              }


              break;
          }


          if ($.isPlainObject(result) && $target) {
            try {
              $target.val(JSON.stringify(result));
            } catch (e) {
              console.log(e.message);
            }
          }


        }
      });




      // Keyboard
      $(document.body).on('keydown', function (e) {


        if (!$image.data('cropper') || this.scrollTop > 300) {
          return;
        }


        switch (e.which) {
          case 37:
            e.preventDefault();
            $image.cropper('move', -1, 0);
            break;


          case 38:
            e.preventDefault();
            $image.cropper('move', 0, -1);
            break;


          case 39:
            e.preventDefault();
            $image.cropper('move', 1, 0);
            break;


          case 40:
            e.preventDefault();
            $image.cropper('move', 0, 1);
            break;
        }


      });




      // 选择 图片 预览图片
      var $inputImage = $('#inputImage');
      var URL = window.URL || window.webkitURL;
      var blobURL;


      if (URL) {






        $inputImage.change(function () {


          var files = this.files;
          var file;


          if (!$image.data('cropper')) {
            return;
          }


          if (files && files.length) {
            file = files[0];


            if (/^image\/\w+$/.test(file.type)) {
              blobURL = URL.createObjectURL(file);
              $image.one('built.cropper', function () {


                // Revoke when load complete
                URL.revokeObjectURL(blobURL);
              }).cropper('reset').cropper('replace', blobURL);
              //$inputImage.val('');
            } else {
              window.alert('请选择一张图片.');
            }
          }
        });
      } else {
        $inputImage.prop('disabled', true).parent().addClass('disabled');
      }


  
        //提交到后台
        $("#subBtn").click(function(){


            //通过 jqueryForm 进行 ajax提交


           $("#cutPicDialog").modal('hide')
         });
        
        
        
        $("#cutPicDialog").on('hidden.bs.modal', function (e) {


         
         $("#image").cropper('destroy').cropper(options);
             
        })
        
        




    });






  </script>




</div>


 
<!-- 结束模态框 -->




</body>


 
 


  
  <script>
  
  
  
  $("#openBtn").click(function()
 {


     $('#cutPicDialog').modal({
         keyboard:false, //键盘 ESC不关闭
         backdrop:'static' //点击空白区 不关闭
   })




 });
  
  
  $("#openBtn").click(function()
 {


     $('#cutPicDialog').modal({
         keyboard:false, //键盘 ESC不关闭
         backdrop:'static' //点击空白区 不关闭
   })




 });
  
  
   //无论如何关闭,都把 image重置
/*   $("#cutPicDialog").on('hidden.bs.modal', function (e) {


      $("#image").cropper('destroy').cropper(options)
    }) */
    
  
  
  </script>
  
  
   <script>
 
 


$(function(){ 


    var options = {  
    url:   "manager/setUserFacePic.html"  ,
    type: "post"  ,
    beforeSubmit:  showRequest,  //提交前处理 
        success:  showResponse,  //处理完成 
        resetForm: false,    //把表单清空 ,由于有图片预览,需要在 showResponse 里单独处理
        dataType:  "json",
   
    };  
  
    $("#userFaceForm").submit(function() {  
          
       $(this).ajaxSubmit(options);  
       // 阻止默认的提交事件
       return false;
       
    });  
}); 
 
 //提交前验证
function showRequest(formData, jqForm, options) {  
    
   if ($("#dataX").val()=="")
  {
  
  return false;
  }
 
   if ($("#dataX").val()=="")
   {
   
   return false;
   }
   
   if ($("#dataY").val()=="")
   {
   
   return false;
   }
   
   if ($("#dataWidth").val()=="")
   {
   
   return false;
   }
   
   if ($("#dataHeigh").val()=="")
   {
   
   return false;
   }
   
 
   
 
    return true;  
}  
  //获取反馈信息
function showResponse(responseText, statusText)  {  
 
  
 
       if (responseText.code==1)
    {
        //使用自定义的弹窗,  可以控制相对于谁弹窗。 而 Layer弹窗默认是屏幕中间
     
        
        $("#dataX").val("");
        $("#dataY").val("");
        $("#dataWidth").val("");
        $("#dataHeigh").val("");
        
        $("#cutPicDialog").modal('hide');
        layer.msg("头像设置成功");
        
        $("#userImage").attr("src","/userFacePic/"+responseText.msg);
       
     
   
 
  
}  


</script>






</html>

</pre>




后台代码





你可能感兴趣的:(cropper本地预览 裁剪,上传到服务器)