公司最近一个项目要用到图片上传的,但是传统的图片上传,没有剪裁功能,非常不人性化
经常看到其他网站,诸如博客之类的,都运用到了图片剪裁上传功能,觉得应该可以借鉴一下,因此折磨了一天,终于把基本的demo给弄出来了。
环境:
Myeclipse 10.0
Tomcat 7.0
jsCropperUI-1.2.2
Struts2
所需要的jar包如下图所示:
jsCropperUI-1.2.2 下载的地址如下:
下载好jsCropperUI,主要需要三个库文件
<scripttype="text/javascript"src="scripts/cropper/lib/prototype.js"language="javascript"></script>
<scripttype="text/javascript"src="scripts/cropper/lib/scriptaculous.js?load=effects,builder,dragdrop"language="javascript"></script>
<scripttype="text/javascript"src="scripts/cropper/cropper.js"language="javascript"></script>
首先编写webRoot下的index.htm
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<font color="red">支持JPG,JPEG,GIF,BMP,PNG文件的上传,限制大小为2MB</font>
<form action="uploadAction.action" method="post"
enctype="multipart/form-data">
<input type="file" name="upload" style="width:450" /> <input
type="submit" value="上传文件" />
</form>
</body>
</html>
其次编写接收原图片的UploadPhotoAction
/*
* @(#)UploadPhotoAction.java
*
* @author zhenfei.zhang
*
* Copyright (c) 2012 Glacier SoftWare Company Limited. All Rights Reserved.
*/
package com.glaciersoft.action;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
/**
*
* @ClassName: UploadPhotoAction
*
* @Description: TODO(这里用一句话描述这个类的作用)
*
* @author zhenfei.zhang
*
* @email zhangzhenfei_email@163.com
*
* @date 2012-5-3 下午1:25:43
*
*
*/
public class UploadPhotoAction extends ActionSupport {
private static final long serialVersionUID = 1L;
private static final int BUFFER_SIZE = 16 * 1024;
// 上传文件域的属性
private File upload;
// 上传文件类型的属性
private String uploadContentType;
// 上传文件名的属性
private String uploadFileName;
// 保存文件的路径
private String savePath;
// 页面中要引用的url
private String pagePath;
@SuppressWarnings("deprecation")
public String saveSrcPhoto() throws Exception {
String imageFileName = new Date().getTime()
+ getExtention(uploadFileName);
String path = ServletActionContext.getRequest().getRealPath(
getSavePath() + "/" + imageFileName);
// 页面引用位置
setPagePath(getSavePath() + "/" + imageFileName);
copy(upload, new File(path));
return "saveSrcPhotoSuccess";
}
private static void copy(File src, File dst) {
try {
InputStream in = null;
OutputStream out = null;
try {
in = new BufferedInputStream(new FileInputStream(src),
BUFFER_SIZE);
out = new BufferedOutputStream(new FileOutputStream(dst),
BUFFER_SIZE);
byte[] buffer = new byte[BUFFER_SIZE];
while (in.read(buffer) > 0) {
out.write(buffer);
}
} finally {
if (null != in) {
in.close();
}
if (null != out) {
out.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static String getExtention(String fileName) {
int pos = fileName.lastIndexOf(".");
return fileName.substring(pos);
}
public File getUpload() {
return upload;
}
public void setUpload(File upload) {
this.upload = upload;
}
public String getUploadContentType() {
return uploadContentType;
}
public void setUploadContentType(String uploadContentType) {
this.uploadContentType = uploadContentType;
}
public String getUploadFileName() {
return uploadFileName;
}
public void setUploadFileName(String uploadFileName) {
this.uploadFileName = uploadFileName;
}
public String getSavePath() {
return savePath;
}
public void setSavePath(String savePath) {
this.savePath = savePath;
}
public String getPagePath() {
return pagePath;
}
public void setPagePath(String pagePath) {
this.pagePath = pagePath;
}
}
然后编写切割图片的Action
/*
* @(#)CutPhotoAction.java
*
* @author zhenfei.zhang
*
* Copyright (c) 2012 Glacier SoftWare Company Limited. All Rights Reserved.
*/
package com.glaciersoft.action;
import org.apache.struts2.ServletActionContext;
import com.glaciersoft.util.ImageHepler;
import com.opensymphony.xwork2.ActionSupport;
/**
*
* @ClassName: CutPhotoAction
*
* @Description: TODO(这里用一句话描述这个类的作用)
*
* @author zhenfei.zhang
*
* @email zhangzhenfei_email@163.com
*
* @date 2012-5-3 下午4:58:37
*
*
*/
public class CutPhotoAction extends ActionSupport {
private static final long serialVersionUID = 8234888222L;
private String fileName;
private int cutX;
private int cutY;
private int cutWidth;
private int cutHeight;
@SuppressWarnings("deprecation")
@Override
public String execute() throws Exception {
try {
ImageHepler.abscut(
ServletActionContext.getRequest().getRealPath(fileName),
cutX, cutY, cutWidth, cutHeight);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public int getCutX() {
return cutX;
}
public void setCutX(int cutX) {
this.cutX = cutX;
}
public int getCutY() {
return cutY;
}
public void setCutY(int cutY) {
this.cutY = cutY;
}
public int getCutWidth() {
return cutWidth;
}
public void setCutWidth(int cutWidth) {
this.cutWidth = cutWidth;
}
public int getCutHeight() {
return cutHeight;
}
public void setCutHeight(int cutHeight) {
this.cutHeight = cutHeight;
}
}
配置文件如下:struts.xml
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.multipart.maxSize" value="9000000" />
<include file="struts-default.xml" />
<package name="GlacierSoftware" extends="struts-default">
<action name="uploadAction" class="com.glaciersoft.action.UploadPhotoAction"
method="saveSrcPhoto">
<param name="savePath">/images_temp</param>
<result name="saveSrcPhotoSuccess">/cropper/cutphoto/cutphoto.jsp</result>
<!-- 上传失败的时候转到的视图 -->
<result name="input">/index.htm</result>
<interceptor-ref name="defaultStack">
<!-- 配置允许上传的文件类型,多个用","分隔 -->
<param name="fileUpload.allowedTypes">
image/bmp,image/png,image/gif,image/jpeg,image/jpg
,image/x-png,
image/pjpeg
</param>
<!-- 配置允许上传的文件大小,单位字节,本例为:5MB -->
<param name="fileUpload.maximumSize">1024*2*1000</param>
</interceptor-ref>
</action>
<action name="cutPhotoAction" class="com.glaciersoft.action.CutPhotoAction">
<result></result>
</action>
</package>
</struts>
package com.glaciersoft.util;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
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 javax.imageio.ImageIO;
public class ImageHepler {
/** */
/**
* 图像切割(改)
*
* @param srcImageFile
* 源图像地址
* @param x
* 目标切片起点x坐标
* @param y
* 目标切片起点y坐标
* @param destWidth
* 目标切片宽度
* @param destHeight
* 目标切片高度
*/
public static void abscut(String srcImageFile, int x, int y, int destWidth,
int destHeight) {
try {
Image img;
ImageFilter cropFilter;
// 读取源图像
BufferedImage bi = ImageIO.read(new File(srcImageFile));
int srcWidth = bi.getWidth(); // 源图宽度
int srcHeight = bi.getHeight(); // 源图高度
if (srcWidth >= destWidth && srcHeight >= destHeight) {
Image image = bi.getScaledInstance(srcWidth, srcHeight,
Image.SCALE_DEFAULT);
cropFilter = new CropImageFilter(x, y, destWidth, destHeight);
img = Toolkit.getDefaultToolkit().createImage(
new FilteredImageSource(image.getSource(), cropFilter));
BufferedImage tag = new BufferedImage(destWidth, destHeight,
BufferedImage.TYPE_INT_RGB);
Graphics g = tag.getGraphics();
g.drawImage(img, 0, 0, null); // 绘制缩小后的图
g.dispose();
// 输出为文件
ImageIO.write(tag, "JPEG", new File(srcImageFile));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
对原图片进行切割的页面cutphoto.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'cutphoto.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<script src="<%=basePath%>/cropper/scriptaculous-js-1.9.0/lib/prototype.js" type="text/javascript"></script>
<script src="<%=basePath%>/cropper/scriptaculous-js-1.9.0/src/scriptaculous.js" type="text/javascript"></script>
<script src="<%=basePath%>/cropper/cropper.js" type="text/javascript"></script>
<script type="text/javascript" charset="utf-8">
function onEndCrop( coords, dimensions ) {
$( 'x1' ).value = coords.x1;
$( 'y1' ).value = coords.y1;
$( 'x2' ).value = coords.x2;
$( 'y2' ).value = coords.y2;
$( 'width' ).value = dimensions.width;
$( 'height' ).value = dimensions.height;
}
// example with a preview of crop results, must have minimumm dimensions
Event.observe(
window,
'load',
function(options) {
new Cropper.ImgWithPreview(
'testImage',
{
minWidth: 200,
minHeight: 120,
ratioDim: { x: 200, y: 120 },
displayOnInit: true,
onEndCrop: onEndCrop,
previewWrap: 'previewArea'
}
)
}
);
</script>
</head>
<body>
<s:debug></s:debug>
<br /><br />
<div id="testWrap">
<img src="<%=basePath%><s:property value="pagePath"/>" alt="test image" id="testImage"/>
</div>
<div id="previewArea" style="float: right;"></div>
<div id="results">
<form action="cutPhotoAction.action" method="post">
<input type="hidden" name="fileName" value="<s:property value="pagePath"/>"/>
<p>
<label for="x1">x1:</label>
<input type="text" name="cutX" id="x1" />
</p>
<p>
<label for="y1">y1:</label>
<input type="text" name="cutY" id="y1" />
</p>
<p>
<label for="x2">x2:</label>
<input type="text" name="x2" id="x2" />
</p>
<p>
<label for="y2">y2:</label>
<input type="text" name="y2" id="y2" />
</p>
<p>
<label for="width">width:</label>
<input type="text" name="cutWidth" id="width" />
</p>
<p>
<label for="height">height</label>
<input type="text" name="cutHeight" id="height" />
</p>
<p>
<input type="submit" value="提交">
</p>
</form>
</div>
</body>
</html>
其实很简单。自动动手试一试吧~
最后源码也放出了:网盘