首先需要引用三个JS文件
<link rel="stylesheet" href="Jcrop/jquery.Jcrop.css">
<script src="Jcrop/jquery-2.2.3.js"></script>
<script src="Jcrop/jquery.Jcrop.js"></script>
然后页面上下面的JS代码是在选择图片的时候通过AJAX上传图片,这里需要注意的是Jquery必须使用2.0以上的版本,否则后台就收不到文件
<script type="text/javascript">
//图片上传的onchange事件,用于上传并回显图片
function uploadImg() {
var formData = new FormData($( "#uploadForm" )[0]);
$.ajax({
url: '${pageContext.request.contextPath}/uploadImag.do' ,
type: 'POST',
data: formData,
async: false,
cache: false,
contentType: false,
processData: false,
success: function (returndata) {
var json=eval("("+returndata+")");
var cropboxdiv=$('#cropboxdiv');//图片回显区域
$('#cropboxdiv').empty();
$("<img id='cropbox' src='"+json.path+"/"+json.fileName+"'>").appendTo(cropboxdiv);
$('#imgPath').val(json.path+"/"+json.fileName);
$('#srcPath').val(json.path);
$('#fileName').val(json.fileName);
$('#cropbox').Jcrop({//初始化Jcrop图片裁剪器
maxSize : [ 150, 170 ],
minSize: [135,135],
onSelect : function(c){//图片选择事件
$('#x').val(c.x);
$('#y').val(c.y);
$('#w').val(c.w);
$('#h').val(c.h);
}
});
}
});
}
//图片裁剪区域选好之后,交给java后台进行裁剪
function cutImg(){
$.ajax({
type:"post",
url:"${pageContext.request.contextPath}/cutImg.do",
cache:false,
data:{
x:$('#x').val(),
y:$('#y').val(),
w:$('#w').val(),
h:$('#h').val(),
srcPath:$('#srcPath').val(),
fileName:$('#fileName').val()
},
success:function(r){
$('#imgPath').val($('#srcPath').val()+"/"+$('#fileName').val());
}
});
}
</script>
<body>
<div id="cropboxdiv">
<img id="cropbox" src="">
</div>
<form id= "uploadForm">
<table>
<tr>
<a href="javascript:void(0);" class="file">选择文件
<input type="file" name="file" οnchange="uploadImg()">
</a>
</tr>
</table>
</form>
<input type="hidden" id="x" />
<input type="hidden" id="y" />
<input type="hidden" id="w" />
<input type="hidden" id="h" />
<input type="hidden" id="imgPath" />
<input type="hidden" id="srcPath" />
<input type="hidden" id="fileName" />
</body>
下面是后台接收前台onchange事件上传的图片,最后将图片的相对路径和文件名封装到一个DTO里面方便传输数据
@RequestMapping("uploadImag")
public void uploadImag(@RequestParam(value = "file", required = false) MultipartFile file,
HttpServletResponse response, HttpServletRequest request) throws Exception{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String date = sdf.format(new Date());
String path = request.getSession().getServletContext()
.getRealPath("img" + File.separator + date);
String[] postfixs = file.getOriginalFilename().split("\\.");
String postfix = postfixs[postfixs.length - 1];
String fileName = new Date().getTime() + "." + postfix;
File targetFile = new File(path, fileName);
if (!targetFile.exists()) {
targetFile.mkdirs();
}
try {
file.transferTo(targetFile);
} catch (Exception e) {
e.printStackTrace();
}
imgCutPathDto icp=new imgCutPathDto();
icp.setFileName(fileName);
icp.setPath(Zealot.SSOIMAGPATH + File.separator+date);
WebUtil.print(response,Json.toJson(icp));
}
这时候原始图片已经回显到了页面,在调用前台的裁剪方法是会访问后台的一个裁剪图片方法,如下
@RequestMapping("cutImg")
public void cutImg(HttpServletResponse response, HttpServletRequest request,String x,String y,String w,String h,String srcPath,String fileName){
int x1=Integer.parseInt(x);
int y1=Integer.parseInt(y);
int w1=Integer.parseInt(w);
int h1=Integer.parseInt(h);
String path = request.getSession().getServletContext()
.getRealPath("/");
CutImg.cutPic(path+srcPath+File.separator+fileName,path+srcPath, x1, y1, w1, h1,fileName);
WebUtil.print(response,"yes");
}
具体裁剪工具类,如下
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Date;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import org.apache.commons.io.FilenameUtils;
public class CutImg {
private static final String JPG_HEX = "ff";
private static final String PNG_HEX = "89";
private static final String JPG_EXT = "jpg";
private static final String PNG_EXT = "png";
public static String getFileExt(String filePath) {
FileInputStream fis = null;
String extension = FilenameUtils.getExtension(filePath);
try {
fis = new FileInputStream(new File(filePath));
byte[] bs = new byte[1];
fis.read(bs);
String type = Integer.toHexString(bs[0]&0xFF);
if(JPG_HEX.equals(type))
extension = JPG_EXT;
if(PNG_HEX.equals(type))
extension = PNG_EXT;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(fis != null)
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return extension;
}
public static boolean cutPic(String srcFile, String outFile, int x, int y,
int width, int height,String fileName) {
FileInputStream is = null;
ImageInputStream iis = null;
try {
// 如果源图片不存在
if (!new File(srcFile).exists()) {
return false;
}
// 读取图片文件
is = new FileInputStream(srcFile);
// 获取文件格式
String ext =getFileExt(srcFile);
//String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
// ImageReader声称能够解码指定格式
Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName(ext);
ImageReader reader = it.next();
// 获取图片流
iis = ImageIO.createImageInputStream(is);
// 输入源中的图像将只按顺序读取
reader.setInput(iis, true);
// 描述如何对流进行解码
ImageReadParam param = reader.getDefaultReadParam();
// 图片裁剪区域
Rectangle rect = new Rectangle(x, y, width, height);
// 提供一个 BufferedImage,将其用作解码像素数据的目标
param.setSourceRegion(rect);
// 使用所提供的 ImageReadParam 读取通过索引 imageIndex 指定的对象
BufferedImage bi = reader.read(0, param);
File tempOutFile = new File(outFile, fileName);
File tempOutFileDir = new File(outFile);
if (!tempOutFileDir.exists()) {
tempOutFileDir.mkdirs();
}
tempOutFile.createNewFile();
ImageIO.write(bi, ext, tempOutFile);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
try {
if (is != null) {
is.close();
}
if (iis != null) {
iis.close();
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
}
}
如此图片裁剪便完成了,原始的图片我在这儿被裁剪后的图片覆盖了,根据之前的上传路径就可以回显裁剪后的图片了