`

页面图片裁切工具jscrop

 
阅读更多

 

 1 文件上传

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>文件上传页面</title>
 
</head>
<body>
<form action="<%=request.getContextPath()%>/userHeadImg/uploadHead.anys" method="post" enctype="multipart/form-data">  
    yourfile: <input type="file" name="myfile"/><br/>  
    <input type="submit" value="上传"/>  
</form>  
</body>
</html>

 

2 文件裁切页面 

  

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>文件裁切页面</title>
<script src="http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js" type="text/ecmascript"></script>
<script type="text/javascript" src="<%=request.getContextPath() %>/script/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="<%=request.getContextPath() %>/script/jscrop/js/jquery.color.js"></script>
<script type="text/javascript" src="<%=request.getContextPath() %>/script/jscrop/js/jquery.Jcrop.js"></script>
<link rel="stylesheet" href="<%=request.getContextPath() %>/script/jscrop/css/jquery.Jcrop.css" type="text/css" />
 
</head>
<body>111111
<form action="<%=request.getContextPath()%>/userHeadImg/cutPic.anys" method="post">  
	<input type="text" name="srcpath" value="${ fileName}"/>
	
    <input type="text" name="x" id="x"/>  
    <input type="text" name="y" id="y"/>  
    <input type="text" name="width" id="width"/>  
    <input type="text" name="height" id="height"/>  
    <input type="submit" value="确定" />  
</form>
<hr />

<img src="<%=request.getContextPath()%>${ path}" alt="" id="target"/>
 
预览:  
<div style="width:105px;height:105px;overflow:hidden; border:1px solid gray;">  
   <img id="preview1" width="105px" height="105px" src="<%=request.getContextPath()%>${ path}"  />  
</div> 

<div style="width:50px;height:50px;overflow:hidden; border:1px solid gray;">  
   <img id="preview2" width="50px" height="50px" src="<%=request.getContextPath()%>${ path}"  />  
</div> 
  
<div style="width:30px;height:30px;overflow:hidden; border:1px solid gray;">  
   <img id="preview3" width="30px" height="30px" src="<%=request.getContextPath()%>${ path}"  />  
</div> 

</body>
<script type="text/javascript">
    var x;
	var y;
	var width;
	var height;
	$(function(){
		var jcrop_api, boundx, boundy;
		 //使原图具有裁剪功能 
		$('#target').Jcrop({
			onChange: updatePreview,
			onSelect: updatePreview,
			aspectRatio: 1
		},function(){
			// Use the API to get the real image size
			var bounds = this.getBounds();
			boundx = bounds[0];
			boundy = bounds[1];
			// Store the API in the jcrop_api variable
			jcrop_api = this;
		});
		 //裁剪过程中,每改变裁剪大小执行该函数 
		function updatePreview(c){
			if (parseInt(c.w) > 0){	
				$('#preview1').css({
					width: Math.round(105/ c.w * boundx) + 'px',  //200 为预览div的宽和高</span>
					height: Math.round(105 / c.h * boundy) + 'px',
					marginLeft: '-' + Math.round(105 / c.w * c.x) + 'px',
					marginTop: '-' + Math.round(105 / c.h * c.y) + 'px'
				});

				$('#preview2').css({
					width: Math.round(50/ c.w * boundx) + 'px',  //200 为预览div的宽和高</span>
					height: Math.round(50 / c.h * boundy) + 'px',
					marginLeft: '-' + Math.round(50 / c.w * c.x) + 'px',
					marginTop: '-' + Math.round(50 / c.h * c.y) + 'px'
				});
				$('#preview3').css({
					width: Math.round(30/ c.w * boundx) + 'px',  //200 为预览div的宽和高</span>
					height: Math.round(30 / c.h * boundy) + 'px',
					marginLeft: '-' + Math.round(30 / c.w * c.x) + 'px',
					marginTop: '-' + Math.round(30 / c.h * c.y) + 'px'
				});
				
				$('#width').val(c.w);  //c.w 裁剪区域的宽
				$('#height').val(c.h); //c.h 裁剪区域的高
				$('#x').val(c.x);  //c.x 裁剪区域左上角顶点相对于图片左上角顶点的x坐标
				$('#y').val(c.y);  //c.y 裁剪区域顶点的y坐标</span>
			}
		  };
	});
  </script>

</html>

 

 

3   文件处理控制器

    

package com.mainbo.master.controller;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
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.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.mainbo.master.util.OperateImage;
import com.mainbo.u3.util.FileUtil;

@Controller
@RequestMapping("/userHeadImg")
public class UserHeadImgController {
	// 日志
	public Logger logger = Logger.getLogger(UserHeadImgController.class);

	@RequestMapping(value = "/uploadHead.anys", method = RequestMethod.POST)
	public ModelAndView uploadHeadImg(@RequestParam MultipartFile myfile,
			ModelAndView model, HttpServletRequest request) throws IOException {
		// 如果只是上传一个文件,则只需要MultipartFile类型接收文件即可,而且无需显式指定@RequestParam注解
		// 如果想上传多个文件,那么这里就要用MultipartFile[]类型来接收文件,并且还要指定@RequestParam注解
		// 并且上传多个文件时,前台表单中的所有<input
		// type="file"/>的name都应该是myfiles,否则参数里的myfiles无法获取到所有上传的文件
		 
		String fileName = null;
		if (myfile.isEmpty()) {
			System.out.println("文件未上传");
		} else {
			System.out.println("文件长度: " + myfile.getSize());
			System.out.println("文件类型: " + myfile.getContentType());
			System.out.println("文件名称: " + myfile.getName());
			System.out.println("文件原名: " + myfile.getOriginalFilename());
			fileName = saveFile(myfile, request,
					getSuffix(myfile.getContentType()));
		}
		model.getModel().put("fileName",  fileName);
		model.getModel().put("path",  FileUtil.getUserHeadImgDir(2,request)+"/"+fileName);
		// model.getModel().put("preview", "/upload/finish/2.png");
		model.setViewName("/fileUploadTest/fileuploadTest1");
		return model;
	}

	@RequestMapping(value = "/cutPic.anys", method = RequestMethod.POST)
	public ModelAndView cutPic(@ModelAttribute OperateImage image,
			ModelAndView model, HttpServletRequest request) throws IOException {
		String fileName = image.getSrcpath();
		image.setSrcpath(FileUtil.getUserHeadImgDir(1 , request )  +"/"+ image.getSrcpath());//拼接文件路径
	 
		// 图片剪切后 的文件路径
		image.setSubpath(FileUtil.getUserHeadImgDir(1,request)+"/"+fileName);
		image.cut(FileUtil.getFileSuffix( fileName ) ); // 执行裁剪操作 执行完后即可生成目标图在对应文件夹内。
		
		//文件存放数据库 
		model.getModel().put("fileName",  fileName);
		model.getModel().put("path",  FileUtil.getUserHeadImgDir(2,request)+"/"+fileName);
		//model.getModel().put("preview", "/upload/finish/2.png");
		model.setViewName("/fileUploadTest/fileuploadTest1");
		return model;
	}

	/**
	 * @param myfile
	 * @param request
	 * @param suffix
	 * @return
	 */
	private String saveFile(MultipartFile myfile, HttpServletRequest request,
			String suffix) {
		BufferedOutputStream bos = null;
		BufferedInputStream bis = null;

		// 如果用的是Tomcat服务器,则文件会上传到\\%TOMCAT_HOME%\\webapps\\YourWebProject\\WEB-INF\\upload\\文件夹中
		String realPath = FileUtil.getUserHeadImgDir(1 , request); 
		// 这里不必处理IO流关闭的问题,因为FileUtils.copyInputStreamToFile()方法内部会自动把用到的IO流关掉,我是看它的源码才知道的
		// FileUtils.copyInputStreamToFile(myfile.getInputStream(), new
		// File(realPath, myfile.getOriginalFilename()));
		String newFileName = FileUtil.getRandomFileName(myfile.getName(),suffix);
		
		File saveFile = new File(new File(realPath), newFileName); // 在该实际路径下实例化一个文件
		// 判断父目录是否存在
		if (!saveFile.getParentFile().exists()) {
			saveFile.getParentFile().mkdirs();
		}
		try {
			bis = new BufferedInputStream(myfile.getInputStream());
			bos = new BufferedOutputStream(new FileOutputStream(saveFile));
			byte[] bs = new byte[1024];
			int len;
			while ((len = bis.read(bs, 0, 1024)) > 0) {
				bos.write(bs, 0, len);
			}
			bis.close();
			bos.close();
			return  newFileName;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (bis != null) {
					bis.close();
				}
				if (bos != null) {
					bos.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	private String getSuffix(String contentType) {
		return contentType.substring(contentType.lastIndexOf("/") + 1);
	}
	
}

  4 文件裁切工具类 

  

package com.mainbo.master.util;

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.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;

//图片剪切的工具类
public class OperateImage {
	// ===源图片路径名称如:c:\1.jpg
	private String srcpath;
	// ===剪切图片存放路径名称.如:c:\2.jpg
	private String subpath;
	// ===剪切点x坐标
	private int x;
	private int y;
	// ===剪切点宽度
	private int width;
	private int height; 
	
	private String type="jpg"; //jpg 或者 png 小写 
	
	public OperateImage() {
	}
	/** 对图片裁剪,并把裁剪完的新图片保存 */
	public void cut(String type) throws IOException {
		setType(type);
		FileInputStream is = null;
		ImageInputStream iis = null;
		try {
			// 读取图片文件
			is = new FileInputStream(srcpath);
			/*
			 * 返回包含所有当前已注册 ImageReader 的 Iterator,这些 ImageReader 声称能够解码指定格式。
			 * 参数:formatName - 包含非正式格式名称 . (例如 "jpeg" 或 "tiff")等 。
			 */
			Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName(type);
			ImageReader reader = it.next();
			// 获取图片流
			iis = ImageIO.createImageInputStream(is);
			/*
			 * <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);
			// 保存新图片
			ImageIO.write(bi, type, new File(subpath));
		} finally {
			if (is != null)
				is.close();
			if (iis != null)
				iis.close();
		}

	}
	public String getSrcpath() {
		return srcpath;
	}
	public void setSrcpath(String srcpath) {
		this.srcpath = srcpath;
	}
	public String getSubpath() {
		return subpath;
	}
	public void setSubpath(String subpath) {
		this.subpath = subpath;
	}
	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}
	public void setY(int y) {
		this.y = y;
	}
	public int getWidth() {
		return width;
	}
	public void setWidth(int width) {
		this.width = width;
	}
	public int getHeight() {
		return height;
	}
	public void setHeight(int height) {
		this.height = height;
	}
	public String getType() {
		return type;
	}
	public void setType(String type) {
		if( type==null || "".equals( type)){
			this.type = "jpg";
			return ;
		}
		if("png".equals(type)){
			this.type = "png";
		}else{
			this.type = "jpg";
		}
	}
	//------------以下是工具类 
	//得到文件的后缀
	public static String getFileSuffix(String fileName){
		if( fileName==null || "".equals(fileName)){
			return null;
		}
		return fileName.substring(fileName.indexOf(".")+1);
	}
	//得到文件的名称根据文件路径 
	public static String getFileName(String filePath){
		if( filePath==null || "".equals(filePath)){
			return null;
		}
		return filePath.substring(filePath.indexOf(File.separator)+1);
	}	
	
	
}

  5 文件工具类 

   

/**
 * 
 */
package com.mainbo.u3.util;

import java.io.File;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;

 
public class FileUtil 
{
	
	/**
	 * 得到随机的文件名称 
	 * @param fileName  无后缀名称 
	 * @param suffix   文件后缀 
	 * @return
	 */
	public static String getRandomFileName(String fileName,String suffix ) {
		Random rm = new Random();
		String newFileName = System.currentTimeMillis() + rm.nextInt(1000)
				+ fileName+ "." + suffix;
		return newFileName;
	}

	/**
	 *  得到随机的文件名称 
	 * @param filePath 文件路径或带有后缀的文件名称
	 * @return
	 */
	public static String getRandomFileName(String filePath) {
		
		if(filePath==null || "".equals(filePath)){
			return "";
		}
		
		String fileName = filePath;
		if(fileName.indexOf( File.separator)!=-1){
			fileName  = fileName.substring(fileName.lastIndexOf( File.separator)+1);
		} 
		
		String suffix = fileName.substring(fileName.lastIndexOf( ".")+1);
		String fileNameNoSuffix = fileName.substring(0,fileName.lastIndexOf( "."));
		
		Random rm = new Random();
		String newFileName = System.currentTimeMillis() + rm.nextInt(1000)
				+ fileNameNoSuffix+ "." + suffix;
		return newFileName;
	}
	
	/**
	 * 得到文件的后缀名称 
	 * @param fileName
	 * @param suffix
	 * @return
	 */
	public static String getFileSuffix(String fileName  ) {
		if(fileName==null || "".equals(fileName)){
			return "";
		}
		return fileName.substring(  fileName.lastIndexOf(".")+1  ).toLowerCase();
	}

	/**
	 * @param type 1 大图  2 剪切后的小图 路径
	 *  1 和2  文件保存使用路径 
	 *  3 和4 页面显示的时候拼接的路径 
	 * @param req
	 * @return
	 */
	public static String getUserHeadImgDir(Integer type,HttpServletRequest request  ) {
		
		if(type==1){
			return request.getServletContext().getRealPath("/")+"/uploadfile/uploadbig"; 
		}else{
			return "/uploadfile/uploadbig";
		}
	}
	
	/**
	 * @author Junming Wang
	 * @param args
	 */
	public static void main(String[] args) {
		File file = new File("");
		 
	}

}

 

 

 

 

 

   

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics