jquery.Jcrop结合JAVA后台实现图片裁剪上传实例

本文介绍了头像裁剪上传功能,用到的技术有  jQuery,springmvc,裁剪插件用的是jcrop(中间遇到很多坑,最终跨越)。

图片上传步骤:

1.用户选择图片

2.将图片传入后台:用户选择图片的时候选择的是各种各样的,但是我们的网页显示图片大小是有限的,所以我们就要在用户选择图片之后将图片添加到后台进行压缩,压缩成我们想要的大小,之后再显示到页面才好

3.利用jcrop裁剪工具对图片进行裁剪并且实时预览

4.点击确定按钮将裁剪用到的参数传入后台,后台图片进行剪切,之后缩放成我们需要的格式

5.最后将图片路径传到前台进行展示

前台页面代码为:

<script src="js-jcrop/jquery.min.js"></script>
<script src="js-jcrop/jquery.Jcrop.js"></script>
<script src="js/jquery-form.js"></script>
<link rel="stylesheet" href="../css/jquery.Jcrop.css" type="text/css" />
<style type="text/css">
/* 控制预览区域大小*/
#preview-pane .preview-container {
 width: 110px;
 height: 110px;
 overflow: hidden;
}
#targetDiv{
 width: 400px;
 height: 400px;
 background-color:#f7fdff;
}
</style> 

<dl class="dialogBox D_uploadLogo">
  <dt class="dialogHeader">
    <span class="title">头像上传</span>
  </dt> 

  <dd class="dialogBody">
    <dl class="bisinessLogo">
      <dt class="title">预览</dt>
      <dd class="img">
        <div id="preview-pane">
          <div class="preview-container">
           <img src="" id="target2" class="jcrop-preview" alt="未选择图片" />
          </div>
         </div>
      </dd>
      <dd class="tc">尺寸:110*110px</dd>
    </dl>
    <dl class="bisinessInfo">
      <dt class="btnBox02">
        <form id="fileUp" action="/file/img/upload" method="post" enctype="multipart/form-data" target="ifm">
          <a class="btnGray" href="javascript:;">
            <span class="text" id="format">选择图片</span>
            <b class="bgR"></b>
            <input type="file" id="file_upload" class="inputFile" name="userphoto"/>
            <input type="hidden" id="w" name="w"/>
            <input type="hidden" id="h" name="h"/>
            <input type="hidden" id="x" name="x"/>
            <input type="hidden" id="y" name="y"/>
          </a>
        </form>
      </dt>
      <dd class="info"> 

        请从本地选择一张照片,支持jpg,png格式  <span id="msg"></span>
        <div id="targetDiv">
          <img src="" id="target" width="400" height="400" alt="未选择图片"/>
        </div>
      </dd>
    </dl>
  </dd>
  <input type="hidden" id="filePathInput" value=""/> 

  <dd class="dialogBottom">
    <a class="btnBlue btn_confirm" href="javascript:;" onclick="photoSummit();"><span class="text">确定</span><b class="bgR"></b></a>
    <a class="btnGray btn_cancel" href="javascript:;" onclick="hideDialog();"><span class="text">取消</span><b class="bgR"></b></a>
  </dd>
</dl>

1.选择图片

<img src="" id="target" width="400" height="400" alt="未选择图片"/>

2.提交:首先大家知道文件上传的时候用到的标签为:<input type="file"/>   但是有时候我们需要用ajax提交文件并且异步提交,我们如果是用form表单提交的话就不是异步,这样我们回到页面就刷新页面,非常的不方便,但是现在ajax还不能支持文件提交的方式,这时候我们就用到了jquery-form.js,这个文件支持我们用ajax提交文件,代码为:

$("#fileUp").<span style="color:#ff0000;">ajaxSubmit</span>({
      type: "POST",
      url:"/file/img/upload",
      dataType: "json",
      contentType:"application/json",
        success: function(parameter){
        $("#target2").attr('src','/upload/'+parameter.fileName);
        $("#filePathInput").val('/upload/'+parameter.fileName);
        if($("#format").text()=="重新上传"){
          jcrop_api.destroy()
        }
        $("#format").text("重新上传");
        //启动jcrop支持
        openJcrop('/upload/'+parameter.fileName);
      },
      error : function(data) {
        alert("ajax传输发生错误!!!");
      }
     });

这样就能将文件用ajax的方式提交到后台,注意这里用的是ajaxSubmit,这个方法对应jquery-form.js,后台代码为:

package com.quanshi.ums.gate.view.rest.controllers;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.quanshi.ums.gate.persistence.entities.Parameters;
import com.quanshi.ums.gate.view.rest.ImgEditor;
 /**
 * 图像上传和修改相关类
 * @author kunpeng.zhao
 *
 */
@Controller
@RequestMapping(value="/file")
public class FileEditorController {
<span style="white-space:pre">  </span>ImgEditor imgEditor = new ImgEditor();
<span style="white-space:pre">  </span>public String filePathFinal = "";
<span style="white-space:pre">  </span>private Logger logger = LoggerFactory.getLogger(FileEditorController.class);
<span style="white-space:pre">  </span>@RequestMapping(value="/img/cutandscale",method=RequestMethod.POST)
<span style="white-space:pre">  </span>public @ResponseBody int cutAndscaleimg(
<span style="white-space:pre">      </span>@RequestParam("w") int w,
<span style="white-space:pre">      </span>@RequestParam("h") int h,
<span style="white-space:pre">      </span>@RequestParam("x") int x,
<span style="white-space:pre">      </span>@RequestParam("y") int y
<span style="white-space:pre">      </span>){
<span style="white-space:pre">    </span>imgEditor.cut(filePathFinal,filePathFinal,x,y,w,h);
<span style="white-space:pre">    </span>imgEditor.scale(filePathFinal, filePathFinal, 110, 110, false);
<span style="white-space:pre">    </span>return 1;
<span style="white-space:pre">  </span>}
<span style="white-space:pre">  </span>
<span style="white-space:pre">  </span>
  @RequestMapping(value="/img/upload",method=RequestMethod.POST)
  public @ResponseBody Parameters addImage(
  <span style="white-space:pre">   </span>@RequestParam("userphoto") MultipartFile file,
  <span style="white-space:pre">   </span>HttpServletRequest request,
  <span style="white-space:pre">   </span>HttpServletResponse response,
  <span style="white-space:pre">   </span>HttpSession session
  <span style="white-space:pre">   </span>){
  <span style="white-space:pre"> </span>String filePath = "";
  <span style="white-space:pre"> </span>try {
  <span style="white-space:pre">   </span>//上传原图
<span style="white-space:pre">      </span>filePath = imgEditor.uploadFile(file, request,session);
<span style="white-space:pre">      </span>filePathFinal = filePath;
<span style="white-space:pre">      </span>//将图片压缩成指定大小
<span style="white-space:pre">      </span>imgEditor.zoomImage(filePath,filePath,400,400);
<span style="white-space:pre">    </span>} catch (IOException e) {
<span style="white-space:pre">      </span>e.printStackTrace();
<span style="white-space:pre">    </span>}
    logger.info("filePath:" + filePath);
    Parameters parameter = new Parameters();
    parameter.setFileName(imgEditor.getFileName(file,request,session));
  <span style="white-space:pre"> </span>return parameter;
  } 

}

我在这规定图片在前台展示的大小为400*400,用到的图片裁剪压缩等的工具类为:

package com.quanshi.ums.gate.view.rest;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date; 

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession; 

import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.multipart.MultipartFile; 

public class ImgEditor {
   /**
   * 改变图片尺寸
   * @param srcFileName 源图片路径
   * @param tagFileName 目的图片路径
   * @param width 修改后的宽度
   * @param height 修改后的高度
   */
  public void zoomImage(String srcFileName,String tagFileName,int width,int height){
     try {
     BufferedImage bi = ImageIO.read(new File(srcFileName));
     BufferedImage tag=new BufferedImage(width,height, BufferedImage.TYPE_INT_RGB);
     tag.getGraphics().drawImage(bi, 0, 0, width, height, null);
     ImageIO.write(tag, "jpg", new File(tagFileName));//画图
     } catch (IOException e) {
     e.printStackTrace();
     }
  } 

  /**
   * 缩放图像(按高度和宽度缩放)
   * @param srcImageFile 源图像文件地址
   * @param result 缩放后的图像地址
   * @param height 缩放后的高度
   * @param width 缩放后的宽度
   * @param bb 比例不对时是否需要补白:true为补白; false为不补白;
   */
  public void scale(String srcImageFile, String result, int height, int width, boolean bb) {
    try {
      double ratio = 0.0; // 缩放比例
      File f = new File(srcImageFile);
      BufferedImage bi = ImageIO.read(f);
      Image itemp = bi.getScaledInstance(width, height, bi.SCALE_SMOOTH);
      // 计算比例
      if ((bi.getHeight() > height) || (bi.getWidth() > width)) {
        if (bi.getHeight() > bi.getWidth()) {
          ratio = (new Integer(height)).doubleValue()
              / bi.getHeight();
        } else {
          ratio = (new Integer(width)).doubleValue() / bi.getWidth();
        }
        AffineTransformOp op = new AffineTransformOp(AffineTransform
            .getScaleInstance(ratio, ratio), null);
        itemp = op.filter(bi, null);
      }
      if (bb) {//补白
        BufferedImage image = new BufferedImage(width, height,
            BufferedImage.TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();
        g.setColor(Color.white);
        g.fillRect(0, 0, width, height);
        if (width == itemp.getWidth(null))
          g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2,
              itemp.getWidth(null), itemp.getHeight(null),
              Color.white, null);
        else
          g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0,
              itemp.getWidth(null), itemp.getHeight(null),
              Color.white, null);
        g.dispose();
        itemp = image;
      }
      ImageIO.write((BufferedImage) itemp, "JPEG", new File(result));
    } catch (IOException e) {
      e.printStackTrace();
    }
  } 

  /**
   * 图像切割(按指定起点坐标和宽高切割)
   * @param srcImageFile 源图像地址
   * @param result 切片后的图像地址
   * @param x 目标切片起点坐标X
   * @param y 目标切片起点坐标Y
   * @param width 目标切片宽度
   * @param height 目标切片高度
   */
  public void cut(String srcImageFile, String result,
      int x, int y, int width, int height) {
    try {
      // 读取源图像
      BufferedImage bi = ImageIO.read(new File(srcImageFile));
      int srcWidth = bi.getHeight(); // 源图宽度
      int srcHeight = bi.getWidth(); // 源图高度
      if (srcWidth > 0 && srcHeight > 0) {
        Image image = bi.getScaledInstance(srcWidth, srcHeight,
            Image.SCALE_DEFAULT);
        // 四个参数分别为图像起点坐标和宽高
        // 即: CropImageFilter(int x,int y,int width,int height)
        ImageFilter cropFilter = new CropImageFilter(x, y, width, height);
        Image img = Toolkit.getDefaultToolkit().createImage(
            new FilteredImageSource(image.getSource(),
                cropFilter));
        BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics g = tag.getGraphics();
        g.drawImage(img, 0, 0, width, height, null); // 绘制切割后的图
        g.dispose();
        // 输出为文件
        ImageIO.write(tag, "JPEG", new File(result));
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  //获得文件名字
  public String getFileName(MultipartFile file, HttpServletRequest request,HttpSession session){
    String FILE_PATH = session.getServletContext().getRealPath("/") + "upload";
    String fileName = file.getOriginalFilename();
    String[] suffixNameArr = fileName.split("\\.");
    String suffixName = suffixNameArr[suffixNameArr.length-1];
    String userName = SecurityContextHolder.getContext().getAuthentication().getName(); 

    return getTime() + userName+"."+suffixName;
  }
  //文件上传,返回文件路径
  public String uploadFile(MultipartFile file, HttpServletRequest request,HttpSession session) throws IOException {
    String FILE_PATH = session.getServletContext().getRealPath("/") + "upload";
    String fileName = getFileName(file,request,session);
    File tempFile = new File(FILE_PATH, fileName);  

    if (!tempFile.getParentFile().exists()) {
      tempFile.getParentFile().mkdir();
    }
    if (!tempFile.exists()) {
      tempFile.createNewFile();
    }
    file.transferTo(tempFile); //将上传文件写到服务器上指定的文件。 

    return FILE_PATH + "\\" + tempFile.getName();
  }  

  /* public static File getFile(String fileName) {
    return new File(FILE_PATH, fileName);
  } */  

  public String getTime(){
    Date date = new Date();
    SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");//设置日期格式
    String nowTime = df.format(date).toString();
    return nowTime;
  }
}

这样就将图片要裁剪的图片路径返回页面展示

3.之后就是图片裁剪了,图片裁剪功能我找了好多插件,最后锁定jcrop,也是因为它的demo打动了我(太好看了),之后就是导入文件,在我这里,我在页面接收后台返回来的图片路径之后启用jcrop,也就是openJcrop()方法,这样就可以加载jcrop插件了,具体大家想进一步了解这个裁剪工具,请到官网细细的研究,我就不再做过多的谈论了。

大家注意,在这里有个大坑,真的是大坑,就是重新选择图片的时候,被jcrop加载过的img的src是不能被修改的,这个当初卡了我好长时间,被jcrop加载一次jcrop就会生成一个自己的编辑对象(我自己的理解),这时候就和原来的img没有关系了,直到最后细细研究api才找到了一个方法,唯一的方法就是将这个jcrop销毁,就是jcrop_api.destroy(),这个有很大的学问,我就提示一点,就是将jcrop_api声明为全局变量,下面贴出js代码(和上边的html是在一个文件下):

<script type="text/javascript"> 

   $(function(){
    var jcrop_api;
   }); 

   $("#file_upload").change(function() {
     $("#msg").text('');
     var oFile = $(this)[0].files[0];
     //判断上传文件大小
     if (oFile.size > 1*1024*1024) {
       $("#msg").text('你选择了太大的文件,请选择一个1M以下的图像文件').css('color','red');
       $(this).val("");
       return;
     } 

     //判断类型
     var filepath=$(this).val();
     var extStart=filepath.lastIndexOf(".");
     var ext=filepath.substring(extStart,filepath.length).toUpperCase();
     if(ext!=".JPEG"&&ext!=".PNG"&&ext!=".JPG"){
      $("#msg").text('请选择一个有效的图像文件(jpg,png是允许的)').css('color','red');
        $(this).val("");
        return;
     } 

    $("#fileUp").ajaxSubmit({
      type: "POST",
      url:"/file/img/upload",
      dataType: "json",
      contentType:"application/json",
      success: function(parameter){
        $("#target2").attr('src','/upload/'+parameter.fileName);
        $("#filePathInput").val('/upload/'+parameter.fileName);
        if($("#format").text()=="重新上传"){
          jcrop_api.destroy()
        }
        $("#format").text("重新上传");
        //启动jcrop支持
        openJcrop('/upload/'+parameter.fileName);
      },
      error : function(data) {
        alert("ajax传输发生错误!!!");
      }
     });
  });
   function photoSummit(){ 

     //alert($("#w").val()+","+$("#h").val()+","+$("#x").val()+","+$("#y").val());
     //$("#fileUp").attr("action", "/file/img/upload").submit();
     if($("#w").val()>0 && $("#h").val()>0){
      $("#fileUp").ajaxSubmit({
        type: "POST",
        url:"/file/img/cutandscale",
        dataType: "json",
        contentType:"application/json",
        success: function(data){
           $("#msg").text('上传头像成功!!!').css('color','red');
           //alert($("#filePathInput").val());
           window.parent.back($("#filePathInput").val());
        },
        error : function(data) {
          alert("ajax传输发生错误!!!");
        }
      });
     }else{
      $("#msg").text('请用鼠标截取图片').css('color','red');
     }
   }
   //启动jcrop
  function openJcrop(imgPath){
    //启动jcrop支持
        var boundx,boundy,
        xsize = $('#preview-pane .preview-container').width(),
        ysize = $('#preview-pane .preview-container').height(); 

        $('#target').Jcrop({
         minSize: [110, 110],
         onChange: updatePreview,
         onSelect: updatePreview,
         aspectRatio: xsize / ysize
        },function(){
         // Use the API to get the real image size
         var bounds = this.getBounds();
         boundx = bounds[0];
         boundy = bounds[1];
         jcrop_api = this;
        });
        jcrop_api.setImage(imgPath);
        function updatePreview(c)
        {
         if (parseInt(c.w) > 0)
         {
          var rx = xsize / c.w;
          var ry = ysize / c.h; 

          $('#preview-pane .preview-container img').css({
           width: Math.round(rx * boundx) + 'px',
           height: Math.round(ry * boundy) + 'px',
           marginLeft: '-' + Math.round(rx * c.x) + 'px',
           marginTop: '-' + Math.round(ry * c.y) + 'px'
          });
          $("#w").val(c.w);
          $("#h").val(c.h);
          $("#x").val(c.x);
          $("#y").val(c.y);
         }
         };
  } 

</script>

这样我们就完成了编辑功能,之后我们点击提交就会将w,h,x,y参数传到后台。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解Java中使用ImageIO类对图片进行压缩的方法

    最近做项目需要图片压缩处理,网上找的方法大都使用了 com.sun.image.codec.jpeg.* 这个包中的JPEGImageEncoder类,引入这个包后一直报错,各种google百度,尝试了各种方法,包括手动引jre中的rt.jar,以及在eclipse中把受访问限制的API提示从ERROR改为WARNING,等等,然而这些都是不好使的,因为后来我发现我的java-7-openjdk-amd64中的rt.jar里边根本就没有com.sun.image.*,貌似这个类在java7中已经

  • Java实现图片与Base64编码互转

    淘宝里面的html用base64转换图片,不知道为什么,不过看起来好像很美好,话不多说,直接上代码: import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import sun.misc.BASE64Decoder; import sun.misc.BA

  • java实现的图片裁剪功能示例

    本文实例讲述了java实现的图片裁剪功能.分享给大家供大家参考,具体如下: PicCut.java: package Tsets; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Iterator; import javax

  • java实现文件上传下载和图片压缩代码示例

    分享一个在项目中用的到文件上传下载和对图片的压缩,直接从项目中扒出来的:) 复制代码 代码如下: package com.eabax.plugin.yundada.utils; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.

  • java裁剪图片并保存的示例分享

    我们将通过以下步骤来学习: 输入图像,指定要处理的图像路径允许用户拖放要剪裁的部分选择后使用 Robot 类来确定剪裁部分的坐标剪裁所选图像并保持接下来我们开始编码部分. Listing1: 引入的类 复制代码 代码如下: import java.awt.Graphics;  import java.awt.Rectangle;  import java.awt.Robot;  import java.awt.event.MouseEvent;  import java.awt.event.Mo

  • 使用Java代码在Android中实现图片裁剪功能

    前言 Android应用中经常会遇到上传相册图片的需求,这里记录一下如何进行相册图片的选取和裁剪. 相册选取图片 1. 激活相册或是文件管理器,来获取相片,代码如下: private static final int TAKE_PICTURE_FROM_ALBUM = 1; private void takePictureFromAlbum() { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("ima

  • Java如何实现图片裁剪预览功能

    在项目中,我们需要做些类似头像上传,图片裁剪的功能,ok看下面文章! 需要插件:jQuery Jcrop 后端代码: package org.csg.upload; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Itera

  • Java图片裁剪和生成缩略图的实例方法

    一.缩略图 在浏览相册的时候,可能需要生成相应的缩略图. 直接上代码: public class ImageUtil { private Logger log = LoggerFactory.getLogger(getClass()); private static String DEFAULT_PREVFIX = "thumb_"; private static Boolean DEFAULT_FORCE = false;//建议该值为false /** * <p>Tit

  • Java实现图片上传到服务器并把上传的图片读取出来

    在很多的网站都可以实现上传头像,可以选择自己喜欢的图片做头像,从本地上传,下次登录时可以直接显示出已经上传的头像,那么这个是如何实现的呢? 下面说一下我的实现过程(只是个人实现思路,实际网站怎么实现的不太清楚) 实现的思路: 工具:MySQL,eclipse 首先,在MySQL中创建了两个表,一个t_user表,用来存放用户名,密码等个人信息, 一个t_touxiang表,用来存放上传的图片在服务器中的存放路径,以及图片名字和用户ID, T_touxiang表中的用户ID对应了t_user中的i

  • JavaWeb实现裁剪图片上传完整代码

    本文实例为大家分享了JavaWeb实现裁剪图片上传完整案例,供大家参考,具体内容如下 实现思路 •使用jcrop插件手机要裁剪图片的坐标  •将收集到的参数传递到后台,在后台使用java图形对象绘制图像进行裁剪 ◦后台处理流程: 1.将上传的图片按按照比例进行压缩后上传到文件服务器,并且将压缩后的图片保存在本地临时目录中. 2.将压缩后的图片回显到页面,使用jcrop进行裁剪,手机裁剪坐标(x,y,width,height) ■@paramx 目标切片起点坐标X ■@param y 目标切片起点

随机推荐