• jcrop+jquery+javaweb 实现头像裁剪、上传


    • (本文原创,引用请注明出处--zhangjieatbky)
    • 环境准备
      • 准备jquery、jcrop的js和css(官网获取)、jquery的文件上传下载组件
     1 <script type="text/javascript" src="<%=path %>/sparknet/manage/ui/accordion/jquery-1.12.4.min.js"></script>
     2 <link rel="stylesheet" href="ref/jquery.Jcrop.min.css"/>
     3 <script type="text/javascript" src="ref/jquery.color.js"></script>
     4 <script type="text/javascript" src="ref/jquery.Jcrop.min.js"></script>
     5 <!-- 文件上传下载组件 -->
     6 <script type="text/javascript" src="<%=path %>/zjfxjk/expertsLib/ref/jquery.ui.widget.js"></script>
     7 <script type="text/javascript" src="<%=path %>/zjfxjk/expertsLib/ref/jquery.iframe-transport.js"></script>
     8 <script type="text/javascript" src="<%=path %>/zjfxjk/expertsLib/ref/jquery.fileupload.js"></script>
     9 <script type="text/javascript" src="<%=path %>/zjfxjk/expertsLib/ref/jquery.fileupload-process.js"></script>
    10 <script type="text/javascript" src="<%=path %>/zjfxjk/expertsLib/ref/jquery.fileupload-validate.js"></script>
    11 <script type="text/javascript" src="<%=path %>/zjfxjk/expertsLib/ref/jquery.form.js"></script>
    12 <script type="text/javascript" src="<%=path %>/zjfxjk/expertsLib/ref/signTrans.js"></script>
      • html代码
     1 <div id="idDivShield2" class="opacity" style="100%;height:100%;z-index:4;top:0px;left:0px;position:absolute;
     2             background-color:#BEBEBE;display:none;"></div>
     3         <div id="idPhotoEditWin" class="opacity2"  style="border: 0px solid red;420px;height:415px;z-index:5;position:absolute;top:-420px;left:400px;
     4         background-color:white;">
     5             <table border="0" style="392px;height:356px">
     6                 <tr style="height:36px;">
     7                     <td  style="260px;36px;border: 0px solid red;" colspan="3">
     8                         <table style="100%">
     9                             <tr>
    10                                 <td id="idTagFakeFileInput" style="80%"></td>
    11                                 <td id="idTagFakeFileBtn" style="20%" align="center">
    12                                     <div id="" style="border:0px solid grey;70px;height:20px;padding-top:3px;margin-right:0px;
    13                                          background-color: #4178be;color:white;cursor: pointer;" align="center" onclick="methods.fakePhotoUpload()">
    14                                            <span>选择文件</span>
    15                                      </div>    
    16                                 </td>
    17                             </tr>
    18                         </table>
    19                         <form id="upload-file" style="100%" method="post" enctype="multipart/form-data" >  
    20                             <input id="upload-btn"  style="100%;display:none;" type="file" name="file"  value="sss" onchange="methods.fileUpload()" />  
    21                         </form>  
    22                     </td>
    23                 </tr>
    24                 <tr style="height:320px;">
    25                     <td>
    26                         <div id="idTagDivPhoto" style="260px;height:300px;border:1px solid #ececec;">
    27                             <!-- <img id = "target" src="none.png" width="240px" height="300px" class="jcrop-preview" alt="附件"> -->
    28                             <!-- 图片长宽高隐藏域 -->
    29                             <input type="hidden" id="x" name="x" /> 
    30                             <input type="hidden" id="y" name="y" /> 
    31                             <input type="hidden" id="w" name="w" /> 
    32                             <input type="hidden" id="h" name="h" />
    33                             <input type="hidden" id="boundx" name="boundx" >
    34                             <input type="hidden" id="boundy" name="boundy" >
    35                         </div>
    36                     </td>
    37                     <td colspan="2">
    38                         <div style="112px;height:152px;border:0px solid green;margin-top:100px;">
    39                              <div>预览:</div>
    40                              <div id = "aa" style=" 112px;height: 132px;overflow: hidden;border:1px solid #ececec" >
    41                                    <!-- <img id = "preview" src="none.png" width="112px" height="132px" class="jcrop-preview" alt="预览" > -->
    42                              </div>
    43                         </div>
    44                     </td>
    45                 </tr>
    46                 <tr style="height:30px;">
    47                     <td colspan="3" align="center">
    48                         <table style="100%;height:30px;">
    49                             <tr>
    50                                 <td align="right">
    51                                     <div id="idQueryBtn" style="border:0px solid grey;50px;height:20px;padding-top:3px;margin-right:10px;
    52                                          background-color: #4178be;color:white;cursor: pointer;" align="center" onclick="methods.realPhotoUpload()">
    53                                            <span>上传</span>
    54                                      </div>    
    55                                 </td>
    56                                 <td align="left">
    57                                     <div id="idQueryBtn" style="border:0px solid grey;50px;height:20px;padding-top:3px;margin-right:10px;
    58                                          background-color: #4178be;color:white;cursor: pointer;" align="center" onclick="methods.closePhotoEditWin()">
    59                                            <span>关闭</span>
    60                                      </div>
    61                                 </td>
    62                             </tr>
    63                         </table>
    64                     </td>
    65                 </tr>
    66             </table>
    67         </div>

     

        • 效果图
        • js逻辑部分,弹框+上传原图+裁剪坐标
        •  1 //图像编辑窗口
           2             popPhotoEditWin : function(){
           3                 $('#upload-btn').val('');
           4                 Ext.getCmp('idFakeFileInput').setValue('');
           5                 var account = Ext.getCmp('idExpertCode').getValue();
           6                 if(!account){
           7                     Ext.MessageBox.alert("提示","请先选定专家账号");
           8                     return;
           9                 }
          10                 //每次打开,将大图删除
          11                 if($('#idPhotoEditWin').data('photoName')){
          12                     $.ajax({
          13                         url:getPath()+"/ExpertLibController.json?deleteOriginalImage=true",    // $('#idPhotoEditWin').data('photoName',obj['msg']);
          14                         data:{originalImageName:$('#idPhotoEditWin').data('photoName')},
          15                         type:'post',
          16                         async:false,
          17                         success:function(e){
          18                             $('#idPhotoEditWin').removeData('photoName');
          19                         }
          20                     });
          21                 }
          22                 $('#idTagDivPhoto').prepend('<img id = "target" src="none.png" width="240px" height="300px" class="jcrop-preview">');
          23                 $('#aa').prepend('<img id = "preview" src="none.png" width="112px" height="132px" class="jcrop-preview" alt="预览" >');
          24                 $('#idDivShield2').show();
          25                 $('#idPhotoEditWin').animate({top:'70px'},500);
          26                 $('#idPhotoEditWin').scrollTop(0);
          27             },
           1 //onchange事件
           2             fileUpload : function(){
           3                 debugger;
           4                 if(!$('#upload-btn').val())
           5                     return;
           6                 Ext.getCmp('idFakeFileInput').setValue($('#upload-btn').val());
           7                 var account = Ext.getCmp('idExpertCode').getValue();
           8                 $('#idTagDivPhoto img').remove();                    //移除jcrop的渲染
           9                 $('#idTagDivPhoto div').remove();
          10                 $('#aa img').remove();
          11                 $('#idTagDivPhoto').prepend('<img id = "target" src="none.png" width="240px" height="300px" class="jcrop-preview">');
          12                 $('#aa').prepend('<img id = "preview" src="none.png" width="112px" height="132px" class="jcrop-preview" alt="预览" >');
          13                 var type = $('#upload-btn').val().split('.')[$('#upload-btn').val().split('.').length-1];
          14                 if(type.toLowerCase()!='jpg' && type.toLowerCase()!='png'){
          15                     Ext.MessageBox.alert("提示","请选择 jpg 或者 png 格式的图片");
          16                     $('#upload-btn').val('');
          17                     Ext.getCmp('idFakeFileInput').setValue('');
          18                     return;
          19                 }
          20                 if($('#upload-btn').val()){
          21                     var form = $('#upload-file');
          22                     var options  = {    
          23                             url:getPath()+'/ExpertLibController.json?photoUpload=true',    
          24                             type:'post',    
          25                             data : {
          26                                 userAccount:account,
          27                                 state:'original',
          28                                 oldName:$('#idPhotoEditWin').data('photoName')
          29                             },
          30                             success:function(data){
          31                                 debugger;
          32                                  var obj = Ext.util.JSON.decode(data);
          33                                  if(obj['success']=='false'){
          34                                      Ext.MessageBox.alert("提示",obj['msg']);
          35                                      $('#upload-btn').val('');
          36                                      Ext.getCmp('idFakeFileInput').setValue('');
          37                                      return;
          38                                  }
          39                                  //D:JavaEEworkspaceseclipseTest.metadata.pluginsorg.eclipse.wst.server.core	mp4wtpwebappszjInfoOSzjfxjkexpertsLibphotos
          40                                  $('#target').attr('src','photos/'+obj['msg']+'');
          41                                  $('#preview').attr('src','photos/'+obj['msg']+'');
          42                                  $('#idPhotoEditWin').data('photoName',obj['msg']);            //注意,在头像编辑窗口中保存该属性
          43                                  methods.jcropTackle();
          44                             }
          45                         };
          46                     form.ajaxSubmit(options);
          47                 }
          48             },
           1 //实际大小头像的上传
           2             realPhotoUpload:function(){
           3                 if(!$('#upload-btn').val()){
           4                     Ext.MessageBox.alert("提示","请先上传头像");
           5                     return;
           6                 }
           7                 var accountPhotoName0 = $('#idPhotoEditWin').data('photoName');        //大图
           8                 var oldRealPhoto0 = accountPhotoName0;
           9                 if(vars.selectArea[2]==0 || vars.selectArea[3]==0){
          10                     Ext.MessageBox.alert("提示","请选中有效区域");
          11                     return;
          12                 }
          13                 debugger;
          14                 $.ajax({
          15                     url:getPath()+"/ExpertLibController.json?photoSelected=true",
          16                     data:{oldRealPhoto:oldRealPhoto0,accountPhotoName:accountPhotoName0,x:vars.selectArea[0],y:vars.selectArea[1],w:vars.selectArea[2],h:vars.selectArea[3]},
          17                     type:'post',
          18                     async:false,
          19                     success:function(e){
          20                         //未做success的判断
          21                         $('#idPopModifyWin').data('realPhotoName',e['bean']);        //注意,这是包含original中的
          22                         methods.closePhotoEditWin();
          23 //                        $('#idTagPopWinPhoto').attr('src','');
          24                         $('#idTagPopWinPhoto').attr('src','photos/'+e['bean']+'');
          25                     }
          26                 });
          27             },
          28             //关闭图像编辑窗口
          29             closePhotoEditWin : function(){
          30                 $('#idPhotoEditWin').animate({top:'-485px'},500,function(){
          31                     $('#idDivShield2').hide();
          32                 });
          33                 $('#idTagDivPhoto img').remove();                    //移除jcrop的渲染
          34                 $('#idTagDivPhoto div').remove();
          35                 $('#aa img').remove();
          36 //                $('#idPopModifyWin').removeData('photoName');        //移除当前窗口的属性
          37             },
          38             jcropTackle : function(path){
          39               var option = {
          40                     x:40,
          41                     y:20,
          42                     w:98,
          43                     h:115,
          44                     t:'target',
          45                     p:'preview',
          46                     o:'aa'
          47                   }
          48               function updatePreview(obj){
          49                   vars.selectArea.length=0;
          50                     if (parseInt(obj.w) > 0){
          51                         var rx = $('#'+option['o']).width()/ obj.w;
          52                         var ry = $('#'+option['o']).height()/ obj.h;
          53                         $('#'+option['p']).css({
          54                              Math.round(rx*$('#'+option['t']).width()) + 'px',
          55                             height: Math.round(ry*$('#'+option['t']).height()) + 'px',
          56                             marginLeft: '-' + Math.round(rx * obj.x) + 'px',
          57                             marginTop: '-' + Math.round(ry * obj.y) + 'px'
          58                         });
          59                     }
          60                     vars.selectArea.push(obj.x);
          61                     vars.selectArea.push(obj.y);
          62                     vars.selectArea.push(obj.w);
          63                     vars.selectArea.push(obj.h);
          64                  }
          65                $('#'+option['t']).Jcrop({
          66                    onChange: updatePreview,
          67                    onSelect: updatePreview,
          68                    aspectRatio: 140/165,
          69                    minSize:[98,115],
          70                    maxSize:[588,693],
          71                    setSelect: [option['x'],option['y'],option['w'],option['h'] ]
          72 //                   bgFade:   true
          73 //                     bgOpacity: .5
          74                 });
          75             },
        • 后台处理:文件上传+图像裁剪
        •  1 public EditJsonX fileUpload(HttpServletRequest request){
           2         EditJsonX editJson = new EditJsonX();
           3         System.out.println("Accessed");
           4         String savePath = request.getSession().getServletContext().getRealPath("/")+"zjfxjk\expertsLib\photos\";
           5         String userAccount = "",state="";
           6         File file = new File(savePath);
           7         if(!file.exists() && !file.isDirectory()){
           8             System.out.println("目录不存在,创建该目录");
           9             file.mkdir();
          10         }
          11         String message ="",uniqueFilename="",oldName="";            //提示信息
          12         
          13         try{
          14             DiskFileItemFactory factory = new DiskFileItemFactory();
          15             ServletFileUpload upload = new ServletFileUpload(factory);        //文件上传解析器
          16             upload.setHeaderEncoding("UTF-8");
          17             if(!ServletFileUpload.isMultipartContent(request)){
          18                 //按照传统方式获取表单数据,非文件内容
          19                 return null;
          20             }
          21             //使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项
          22             List<FileItem> list = upload.parseRequest(request);
          23             for(FileItem item : list){
          24                 //如果fileitem中封装的是普通输入项的数据
          25                 if(item.isFormField()){
          26                     String name = item.getFieldName();
          27                     //解决普通输入项的数据的中文乱码问题
          28                     String value = item.getString("UTF-8");
          29                     if(name.equals("userAccount")){
          30                         userAccount=value;
          31                     }else if(name.equals("state")){
          32                         state=value;
          33                     }else if(name.equals("oldName")){
          34                         oldName=value;
          35                     }
          36 //                    uniqueFilename = value;
          37                     //value = new String(value.getBytes("iso8859-1"),"UTF-8");
          38                     System.out.println(name + "=" + value);
          39                 }
          40             }
          41             for(FileItem item : list){
          42                 if(!item.isFormField()){
          43                     //如果fileitem中封装的是上传文件
          44                     //得到上传的文件名称,
          45                     String filename = item.getName();
          46                     if(item.getSize()>1024*200){
          47                         editJson.setSuccess(false);
          48                         editJson.setBean("上传文件大小不能超过200kb");
          49                         return editJson;
          50                     }else if(item.getSize()<1024*10){
          51                         editJson.setSuccess(false);
          52                         editJson.setBean("上传文件大小不能小于10kb");
          53                         return editJson;
          54                     }
          55                     System.out.println(filename);
          56                     if(filename==null || filename.trim().equals("")){
          57                         continue;
          58                     }
          59                     String [] filetypes = filename.split("\.");
          60                     String fileType = filetypes[filetypes.length-1];
          61                     if(!fileType.equals("jpg") && !fileType.equals("pdf") && !fileType.equals("doc") && !fileType.equals("docx")){
          62                         editJson.setSuccess(false);
          63                         editJson.setBean("格式错误,请使用*.jpg、*.png 的文件");
          64                         return editJson;
          65                     }
          66                     //注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如: c:a1.txt,而有些只是单纯的文件名,如:1.txt
          67                     //处理获取到的上传文件的文件名的路径部分,只保留文件名部分
          68                     //UUID.randomUUID().toString().replaceAll("-", "")
          69                     uniqueFilename = userAccount+state+"@"+UUID.randomUUID().toString().replaceAll("-", "")+"."
          70                             +filename.substring(filename.lastIndexOf("\")+1).split("\.")[1];
          71                     
          72                     //获取item中的上传文件的输入流
          73                     InputStream in = item.getInputStream();
          74                     //创建一个文件输出流
          75                     FileOutputStream out = new FileOutputStream(savePath + uniqueFilename);
          76                     IOUtils.copy(in, out);
          77                     in.close();
          78                     out.close();
          79                     //删除处理文件上传时生成的临时文件
          80 //                    item.delete();
          81                     message = "文件上传成功!";
          82                     new File(savePath+oldName).delete();            //删除旧头像
          83                     System.out.println(message);
          84                 }
          85             }
          86         }catch(Exception e){
          87             message= "文件上传失败!";
          88             System.out.println(message);
          89             throw new RuntimeException("上传文件过程中出现错误",e);
          90         }
          91         editJson.setSuccess(true);
          92         editJson.setBean(uniqueFilename);
          93         return editJson;
          94     }
        • 头像编辑+保存
        •  1     /**
           2      * 头像编辑
           3      * @param request
           4      * @param response
           5      * @return
           6      */
           7     @ResponseBody
           8     @RequestMapping(params="photoSelected")
           9     public EditJsonX photoSelected(HttpServletRequest request, HttpServletResponse response){
          10         EditJsonX editJsonX = new EditJsonX();
          11         //包含了可能的文件后缀名,这是原始图片,这个文件名中有 original。例如,18521452148original.jpg
          12         String accountPhotoName = request.getParameter("accountPhotoName");
          13         String oldRealPhoto = StringUtil.nullToEmpty(request.getParameter("oldRealPhoto"));
          14         String savePath = request.getSession().getServletContext().getRealPath("/")+"zjfxjk\expertsLib\photos\";
          15         String pSavePath = savePath+accountPhotoName;
          16         int x = (int)Math.round(Double.parseDouble(request.getParameter("x")));
          17         int y = (int)Math.round(Double.parseDouble(request.getParameter("y")));
          18         int w = (int)Math.round(Double.parseDouble(request.getParameter("w")));
          19         int h = (int)Math.round(Double.parseDouble(request.getParameter("h")));
          20         abscut(accountPhotoName,pSavePath, x, y,w,h, request);
          21         editJsonX.setSuccess(true);
          22         accountPhotoName = accountPhotoName.replace("original", "real");
          23         editJsonX.setBean(accountPhotoName);
          24         //删除原图
          25         if(!oldRealPhoto.equals(""))
          26             new File(savePath+oldRealPhoto).delete();
          27         return editJsonX;
          28     }
           1 /**
           2      * 截取选中的区域,并保存
           3      * @param srcImageFile
           4      * @param x
           5      * @param y
           6      * @param w
           7      * @param h
           8      */
           9     private static void abscut(String accountPhotoName ,String srcImageFile,int x,int y,int destWidth,int destHeight,HttpServletRequest request){
          10         try{
          11             Image img;
          12             ImageFilter cropFilter;
          13             BufferedImage bi = ImageIO.read(new File(srcImageFile));            //读取源文件
          14             int srcWidth = bi.getWidth(); // 源图宽度
          15             int srcHeight = bi.getHeight(); // 源图高度
          16             if (srcWidth >= destWidth && srcHeight >= destHeight) {
          17                 Image image = bi.getScaledInstance(srcWidth, srcHeight,Image.SCALE_DEFAULT);
          18 
          19                 /* ****************************************
          20                 *  判断原图的宽高和DIV宽高的大小
          21                 *  根据图片外层DIV的宽度,选择的起始点则有相对变化
          22                 *************************************** */
          23                 int x1 = (x*srcWidth)/240;
          24                 int y1 = (y*srcHeight)/300;
          25 //                int w = destWidth*(srcWidth/240);
          26                 int w = (destWidth*srcWidth)/240;
          27 //                int h = destHeight*(srcHeight/300);
          28                 int h = (srcHeight*destHeight)/300;
          29 
          30                 // 四个参数分别为图像起点坐标和宽高
          31                 // 即: CropImageFilter(int x,int y,int width,int height)
          32                 cropFilter = new CropImageFilter(x1, y1, w, h);
          33                 img = Toolkit.getDefaultToolkit().createImage(
          34                 new FilteredImageSource(image.getSource(), cropFilter));
          35                 BufferedImage tag = new BufferedImage(w, h,BufferedImage.TYPE_INT_RGB);
          36                 Graphics g = tag.getGraphics();
          37                 g.drawImage(img, 0, 0, null); // 绘制缩小后的图
          38                 g.dispose();
          39                 // 输出为文件
          40                 accountPhotoName = accountPhotoName.replace("original", "real");
          41                 String savePath = request.getSession().getServletContext().getRealPath("/")+"zjfxjk\expertsLib\photos\"+accountPhotoName;
          42                 ImageIO.write(tag, "JPEG", new File(savePath));
          43             }
          44         }catch (Exception e) {
          45             e.printStackTrace();
          46         }
          47     }

        • 在做人员库的时候,为了保证图片的加载速度,可以将这些小文件保存在服务器的磁盘上,但需要对文件进行有效关闭,避免垃圾文件的产生。因此需要配上文件处理方法
      •  1 //用户检查自己的original文件并删除
         2     public void deleteOriginalFile(String username0,HttpServletRequest request){
         3         String username = username0;
         4         List<Map<String,Object>> list = expertLibDao.getFileName(new Object[]{username});
         5         if(list.size()==0)
         6             return;
         7         String filename = list.get(0).get("FILE_NAME")+"";
         8         String path = request.getSession().getServletContext().getRealPath("/")+"zjfxjk\expertsLib\photos\";
         9         String [] names2 = new File(path).list();
        10         int len = names2.length;
        11         for(int i=0;i<len;i++){
        12             if(names2[i].contains(username) && !names2[i].equals(filename))
        13                 new File(path+names2[i]).delete();
        14         }
        15     }
        16     
        17     //比较硬盘上的文件名和附件表中的文件名
        18     public void compareFilename(HttpServletRequest request) throws Exception{
        19         List<Map<String,Object>> listMap = expertLibDao.getFilenames();
        20         int size = listMap.size();
        21         String [] names1 = new String[size];        //数据库中的filename
        22         for(int i=0;i<size;i++)
        23             names1[i]=(listMap.get(i).get("FILE_NAME")+"");
        24         String path = request.getSession().getServletContext().getRealPath("/")+"zjfxjk\expertsLib\photos\";
        25         String [] names2 = new File(path).list();
        26         int len = names2.length;
        27         for(int i = 0;i < size;i++){
        28             if(len>0){
        29                 for(int j=0;j<len;j++){
        30                     int count = 0;
        31                     if(!names2[j].equals(names1[i])){
        32                         //将磁盘上的文件和数据库中的文件做比较
        33                         count++;
        34                         if(count==len){
        35                                 List<InputStream> temp = expertLibDao.writeToDisk(new Object[]{names2[j]});
        36                                 if(temp.size()==0)
        37                                     continue;
        38                                 InputStream is = temp.get(0); 
        39                                 FileOutputStream fos = new FileOutputStream(path+names2[j]);
        40                                 IOUtils.copy(is,fos);
        41                                 System.out.println("将文件:"+names2[j]+" 写入到磁盘中");
        42                         }
        43                     }else{
        44                         break;
        45                     }
        46                 }
        47             }else{
        48                 List<InputStream> temp = expertLibDao.writeToDisk(new Object[]{names1[i]});
        49                 if(temp.size()==0)
        50                     continue;
        51                 InputStream is = temp.get(0); 
        52                 FileOutputStream fos = new FileOutputStream(path+names1[i]);
        53                 IOUtils.copy(is,fos);
        54                 System.out.println("将文件:"+names1[i]+" 写入到磁盘中");
        55             }
        56         }
        57         for(int i=0;i<len;i++){
        58             for(int j=0;j<size;j++){
        59                 //将数据库中的文件与磁盘上的文件做比较
        60                 int count = 0;
        61                 if(!names1[j].equals(names2[i]) && names2[i].contains("real")){
        62                     count++;
        63                     if(count==size){
        64                         new File(path+names2[i]).delete();
        65                     }
        66                 }else{
        67                     break;
        68                 }
        69             }
        70         }
        71     }
  • 相关阅读:
    路由器基础配置之ospf基础配置
    路由器基础配置之广播多路访问链路上的ospf
    路由器基础设置之ospf
    linux命令之文件系统权限操作常用命令
    路由器基础配置之路由重分布
    路由器配置 之 DHCP+DHCP中继服务配置
    路由器配置 之 PAP与CHAP认证
    基于链路的OSPF MD5口令认证
    压缩和归档操作(16个命令)
    基于链路的OSPF简单口令认证
  • 原文地址:https://www.cnblogs.com/zhangjieatbky/p/8137183.html
Copyright © 2020-2023  润新知