首先,Java代码里带一个获取ImageReader的Iterator
/**
* 从网上摘抄的。
* 返回包含所有当前已注册 ImageReader 的 Iterator,这些 ImageReader 声称能够解码指定格式。
* 参数:postFix - 包含非正式格式名称 .(例如 "jpeg" 或 "tiff")等 。
*
* @param postFix
* 文件的后缀名
* @author 刘各欢
* @return
*/
public Iterator<ImageReader> getImageReadersByFormatName(String postFix) {
switch (postFix) {
case "jpg":
return ImageIO.getImageReadersByFormatName("jpg");
case "jpeg":
return ImageIO.getImageReadersByFormatName("jpeg");
case "gif":
return ImageIO.getImageReadersByFormatName("gif");
case "bmp":
return ImageIO.getImageReadersByFormatName("bmp");
case "png":
return ImageIO.getImageReadersByFormatName("png");
default:
return ImageIO.getImageReadersByFormatName("jpg");
}
}
第一步,用jQuery.form.js的ajaxSubmit()提交上传的原始图片,对图片进行缩放并返回等比例大小的图片,限制返回的图片最大尺寸为1000px X 500px
Java核心代码如下:
/**
*
* imgFileZoom:传入一个图片文件输入流,写入缩放后的图片到输出流
*
* @author 刘各欢
* @param postFix
* @param in
* @param out
* @param showHeight 网页显示区域的高
* @param showWidth 网页显示区域的宽
* @return
* @throws IOException
* @since Ver 1.1
*/
public Map<String,String> imgFileZoom(String postFix,InputStream in,FileOutputStream out,int showHeight,int showWidth) throws IOException{
//FileInputStream is = null;
ImageInputStream iis = null;
Map<String,String> map = new HashMap<String,String>();
try {
// 读取图片文件
//is = new FileInputStream(in);
// 获取文件的后缀名
System.out.println("图片格式为:" + postFix);
/*
* 返回包含所有当前已注册 ImageReader 的 Iterator,这些 ImageReader 声称能够解码指定格式。
* 参数:formatName - 包含非正式格式名称 .(例如 "jpeg" 或 "tiff")等 。
*/
Iterator<ImageReader> it = this.getImageReadersByFormatName(postFix);
ImageReader reader = it.next();
// 获取图片流
iis = ImageIO.createImageInputStream(in);
/*
* <p>iis:读取源.true:只向前搜索 </p>.将它标记为 ‘只向前搜索’。
* 此设置意味着包含在输入源中的图像将只按顺序读取,可能允许 reader 避免缓存包含与以前已经读取的图像关联的数据的那些输入部分。
*/
reader.setInput(iis, true);
int realWidth = reader.getWidth(0);
int realHeight = reader.getHeight(0);
double ratio = 1.0;
if(realWidth>showWidth){
BigDecimal d1 = new BigDecimal(showWidth);
BigDecimal d2 = new BigDecimal(realWidth);
ratio = d1.divide(d2, 8,BigDecimal.ROUND_HALF_UP).doubleValue();
}else if(realHeight>showHeight){
BigDecimal d1 = new BigDecimal(showHeight);
BigDecimal d2 = new BigDecimal(showHeight);
ratio = d1.divide(d2, 8,BigDecimal.ROUND_HALF_UP).doubleValue();
}else{
ratio = 1.0;
}
BigDecimal ratioDecimal = new BigDecimal(ratio);
BigDecimal realWidthDecimal = new BigDecimal(realWidth);
BigDecimal realHeightDecimal = new BigDecimal(realHeight);
BigDecimal outputWidthDecimal = BigDecimal.ONE;
BigDecimal outputHeightDecimal = BigDecimal.ONE;
outputWidthDecimal = realWidthDecimal.multiply(ratioDecimal);
outputHeightDecimal = realHeightDecimal.multiply(ratioDecimal);
int outputWidth = outputWidthDecimal.intValue();
int outputHeight = outputHeightDecimal.intValue();
//装入最终转换过的图片的宽高
map.put("outputWidth", String.valueOf(outputWidth));
map.put("outputHeight", String.valueOf(outputHeight));
/*
* 使用所提供的 ImageReadParam 读取通过索引 imageIndex 指定的对象,并将 它作为一个完整的
* BufferedImage 返回。
*/
BufferedImage bi = reader.read(0);
/*
* 缩放图片
*/
Image imageSmall = bi.getScaledInstance(outputWidth, outputHeight, Image.SCALE_DEFAULT);
BufferedImage small = new BufferedImage(outputWidth, outputHeight, BufferedImage.TYPE_INT_RGB);
Graphics g = small.getGraphics();
g.drawImage(imageSmall, 0, 0, null); // 绘制缩小后的图 将Image绘制到BufferedImage中
g.dispose();
//写入新图片到输出流
ImageIO.write(small, postFix, out);
} finally {
if (in != null)
in.close();
if (iis != null)
iis.close();
if (out != null)
out.close();
}
return map;
}
/**
*
* updateZoomTxService:对上传的头像图片进行缩放,并返回一些参数
*
* @author 刘各欢
* @param pic
* @param req
* @return
* @since Ver 1.1
*/
public Map<String,Object> uploadZoomTx(MultipartFile pic,String uid,HttpServletRequest req){
//从CommonInfo中读取上传文件的路径
String pathString = CommonInfo.touxiangPath+"/zoom/";
String fileName = "";
Map<String,Object> map = new HashMap<String,Object>();
//判断文件是否已经被获取到
if (pic.getSize() > 0) {
//user.setImage(pathString + pic.getOriginalFilename());
//判断文件存储路径是否存在
File file = new File(pathString);
if (!file.exists() && !file.isDirectory()) {
file.mkdirs();
}
try {
String ext=pic.getOriginalFilename().substring(pic.getOriginalFilename().lastIndexOf(".")+1,pic.getOriginalFilename().length());
fileName = System.currentTimeMillis()+uid+"."+ext;
//创建缩放过的文件输出流
FileOutputStream fout = new FileOutputStream(pathString + fileName );
map.put("imgInfo",this.imgFileZoom(ext.toLowerCase(),pic.getInputStream(),fout,500,1000));
map.put("imgUrl", fileName);
if(fout!=null)
fout.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return map;
}
前台核心代码(ajaxSubmit()及成功后的触发):
$("#uploadTxBtn").click(function(){
var option = {
type: "post",
success : function(data){
zoomPicName = data['imgUrl'];
$("#p_img").attr("src", "../../touxiang/zoom/"+data['imgUrl']);
$("#p_img").show();
$("#preview_block").show();
$("#p_img_preview").attr("src", "../../touxiang/zoom/"+data['imgUrl']);
$("#p_img").width(data['imgInfo']['outputWidth']);
$("#p_img").height(data['imgInfo']['outputHeight']);
$("#uploadZoomTx").height(parseInt(data['imgInfo']['outputHeight'])+150);
caijian();
}
};
$("#uploadZoomTx").ajaxSubmit(option);
});
Jcrop相关初始化的js代码:
function caijian(){
// Create variables (in this scope) to hold the API and image size
var jcrop_api, boundx, boundy;
$('#p_img').Jcrop({
onChange: updatePreview,
onSelect: updatePreview,
aspectRatio: 1,
setSelect: [0,0,100,100]
},function(){
// Use the API to get the real image size
var bounds = this.getBounds();
boundx = bounds[0];
boundy = bounds[1];
console.log(1111);
console.log(bounds);
// Store the API in the jcrop_api variable
jcrop_api = this;
});
function updatePreview(c)
{
if (parseInt(c.w) > 0)
{
console.log(c);
img_x = c.x;
img_y = c.y;
img_w = c.w;
img_h = c.h;
var rx = 100 / c.w;
var ry = 100 / c.h;
$('#p_img_preview').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'
});
}
};
}
第二步:
用户拖拽完裁剪框,点击裁剪按钮之后,上传四个参数,分别是起始点的横纵坐标和裁剪区域的宽度高度,
此次过程只上传参数,并没有上传图片,后台根据参数对上一步已经缩放的图片再次进行裁剪和缩放。
js代码略去,后台Java核心代码如下:
/**
*
* imgFileCut:传入一个图片文件输入流,写入裁减后的图片到输出流
*
* @author 刘各欢
* @param postFix
* @param in
* @param out
* @param x
* @param y
* @param width
* @param height
* @param showHeight
* @param showWidth
* @throws IOException
* @since Ver 1.1
*/
public void imgFileCut(String postFix,InputStream in,FileOutputStream out,int x,int y,int width,int height) throws IOException{
ImageInputStream iis = null;
try {
/*
* 返回包含所有当前已注册 ImageReader 的 Iterator,这些 ImageReader 声称能够解码指定格式。
* 参数:formatName - 包含非正式格式名称 .(例如 "jpeg" 或 "tiff")等 。
*/
Iterator<ImageReader> it = getImageReadersByFormatName(postFix);
ImageReader reader = it.next();
// 获取图片流
iis = ImageIO.createImageInputStream(in);
/*
* <p>iis:读取源.true:只向前搜索 </p>.将它标记为 ‘只向前搜索’。
* 此设置意味着包含在输入源中的图像将只按顺序读取,可能允许 reader 避免缓存包含与以前已经读取的图像关联的数据的那些输入部分。
*/
reader.setInput(iis, true);
/*
* <p>描述如何对流进行解码的类<p>.用于指定如何在输入时从 Java Image I/O
* 框架的上下文中的流转换一幅图像或一组图像。用于特定图像格式的插件 将从其 ImageReader 实现的
* getDefaultReadParam 方法中返回 ImageReadParam 的实例。
*/
ImageReadParam param = reader.getDefaultReadParam();
/*
* 图片裁剪区域。Rectangle 指定了坐标空间中的一个区域,通过 Rectangle 对象
* 的左上顶点的坐标(x,y)、宽度和高度可以定义这个区域。
*/
Rectangle rect = new Rectangle(x, y, width, height);
// 提供一个 BufferedImage,将其用作解码像素数据的目标。
param.setSourceRegion(rect);
/*
* 使用所提供的 ImageReadParam 读取通过索引 imageIndex 指定的对象,并将 它作为一个完整的
* BufferedImage 返回。
*/
BufferedImage bi = reader.read(0, param);
/*
* 缩放图片
*/
Image imageSmall = bi.getScaledInstance(100, 100, Image.SCALE_DEFAULT);
BufferedImage small = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
Graphics g = small.getGraphics();
g.drawImage(imageSmall, 0, 0, null); // 绘制缩小后的图 将Image绘制到BufferedImage中
g.dispose();
// 保存新图片
ImageIO.write(small, postFix, out);
} finally {
if (in != null)
in.close();
if (iis != null)
iis.close();
if (out != null)
out.close();
}
}
public String saveTx(String zoomedImageName, String img_x, String img_y,
String img_w, String img_h) {
String zoomedImagePath = CommonInfo.touxiangPath+"/zoom/"+zoomedImageName;
String finalImagePath = CommonInfo.touxiangPath+zoomedImageName;
File zoomedImagefile = new File(zoomedImagePath);
try {
InputStream in = new FileInputStream(zoomedImagefile);
File finalImage = new File(finalImagePath);
FileOutputStream out = new FileOutputStream(finalImage);
int x = new BigDecimal(img_x).intValue();
int y = new BigDecimal(img_y).intValue();
int w = new BigDecimal(img_w).intValue();
int h = new BigDecimal(img_h).intValue();
String postFix=zoomedImageName.substring(zoomedImageName.lastIndexOf(".")+1,zoomedImageName.length()).toLowerCase();
this.imgFileCut(postFix, in, out, x, y, w, h);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("保存头像失败");
return "error";
}
return "success";
}
Control中的主调用方法:
/**
*
* updateZoomTx:对上传的原始头像进行等比例缩放,并返回文件名等一些参数
*
* @author 刘各欢
* @param pic
* @param req
* @return
* @since Ver 1.1
*/
@ResponseBody
@RequestMapping(value = "/uploadZoomTx.do")
public Map<String,Object> updateZoomTx(MultipartFile pic,HttpServletRequest req){
Map<String,Object> map = null;
if(req.getSession()!=null&&req.getSession().getAttribute("curruser")!=null){
String uid = "";
uid = ((User)(req.getSession().getAttribute("curruser"))).getId();
map =userService.uploadZoomTx(pic,uid,req);
}else{
map=new HashMap<String,Object>();
map.put("error","error");
}
return map;
}
/**
*
* saveTx: 对上一步缩放过的图像进行裁剪并缩放,存在本地硬盘
*
* @author 刘各欢
* @param zoomedImageName
* @param img_x
* @param img_y
* @param img_w
* @param img_h
* @param req
* @return
* @since Ver 1.1
*/
@ResponseBody
@RequestMapping(value = "/saveTx.do")
public String saveTx(String zoomedImageName,String img_x,String img_y,String img_w,String img_h,HttpServletRequest req){
String re =userService.saveTx( zoomedImageName,img_x, img_y, img_w, img_h);
if(req.getSession()!=null&&req.getSession().getAttribute("curruser")!=null){
User user = (User)(req.getSession().getAttribute("curruser"));
user.setImage(zoomedImageName);
userService.saveOrUpdate(user);
return "ok";
}else{
return "error";
}
}
相关资源:http://download.csdn.net/detail/lgh06/8343359免积分
预览效果:
版权声明:本文为博主原创文章,未经博主允许不得转载。