利用jQuery與Java實現在線圖片的剪切
一 參考資料
1 jquery Jcrop 頭像,logo截圖
http://terje.blog.163.com/blog/static/11924371201101311319664/
2 javascript+java截取圖像,圖像處理
http://www.blogjava.net/b47248054/articles/200685.html
3 js+java 截取照片中的頭像
http://blog.csdn.net/dsj188/article/details/4313662
4 java+jsp 截頭像圖片
http://ldf2008rw.iteye.com/blog/502793
5 Java生成縮略圖之Thumbnailator
http://rensanning.iteye.com/blog/1545708
Thumbnailator 是一個為Java界面更流暢的縮略圖生成庫。從API提供現有的圖像文件和圖像對象的縮略圖中簡化了縮略過程,兩三行代碼就能夠從現有圖片生成縮略圖,且 允許微調縮略圖生成,同時保持了需要寫入到最低限度的代碼量。同時還支持根據一個目錄批量生成縮略圖。 http://code.google.com/p/thumbnailator/ 這個不錯!支持!
二 解決思路
1 通過smart-upload文件上傳組件將圖片上傳到服務器,并得到圖片文件地址傳遞到前臺的img組件顯示
2 在客戶端用JS獲取圖片X坐標,Y坐標,寬度和高度這四個參數并設置到隱藏元素.
3 java后臺根據圖片關鍵的四個參數實現圖片剪切并在服務器端生成圖片文件
4 通過生成圖片的地址在前臺展現
開發環境: XP3
開發工具: JDK1.6+MyEclipse6.5+Tomcat6
工程圖片:
三 實現方式
1 選用JQuery插件:Jcrop
官方網站: http://deepliquid.com/content/Jcrop.html
項目地址: http://code.google.com/p/jcrop/
效果圖片如下:
2 通過圖片剪切工具類,主要代碼如下:
</div>
- /**
- * 圖像切割(改) *
- * @param srcImageFile 源圖像地址
- * @param dirImageFile 新圖像地址
- * @param x 目標切片起點x坐標
- * @param y 目標切片起點y坐標
- * @param destWidth 目標切片寬度
- * @param destHeight 目標切片高度
- */
- public static void abscut(String srcImageFile,String dirImageFile, 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);
- // 改進的想法:是否可用多線程加快切割速度
- // 四個參數分別為圖像起點坐標和寬高
- // 即: CropImageFilter(int x,int y,int width,int height)
- 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(dirImageFile));
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
</div>
四 具體代碼如下:
1 index.jsp(上傳圖片頁面)
</div>
- <%@ page language="java" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
- <%
- 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></title>
- <meta http-equiv="pragma" content="no-cache">
- <meta http-equiv="cache-control" content="no-cache">
- <meta http-equiv="expires" content="0">
- <script src="/scripts/clearFile.js" type="text/javascript"></script>
- <script type="text/javascript">
- /**檢查圖片上傳類型*/
- function checkImgType(obj){
- var imgFile = '';
- //獲取圖片的全路徑
- var imgFilePath = getImgFullPath(obj);
- var endIndex = imgFilePath.lastIndexOf("\\");
- var lastIndex = imgFilePath.length-endIndex-1;
- if (endIndex != -1)
- imgFile= imgFilePath.substr(endIndex+1,lastIndex);
- else
- imgFile = imgFilePath;
- var tag = true;
- endIndex = imgFilePath.lastIndexOf(".");
- if (endIndex == -1)
- tag = false;
- var ImgName = imgFilePath.substr(endIndex+1,lastIndex);
- ImgName = ImgName.toUpperCase();
- if (ImgName !="GIF" && ImgName !="JPG" && ImgName !="PNG" && ImgName !="BMP"){
- tag=false;
- }
- if (!tag) {
- alert("上傳圖片的文件類型必須為: *.gif,*.jpg,*.png,*.bmp,請重新選擇!")
- Upload.clear(obj);
- return false;
- }
- document.form1.submit();
- }
- function getImgFullPath(obj) {
- if (obj) {
- //ie
- if (window.navigator.userAgent.indexOf("MSIE") >= 1) {
- obj.select();
- return document.selection.createRange().text;
- }
- //firefox
- else if (window.navigator.userAgent.indexOf("Firefox") >= 1) {
- if (obj.files) {
- return obj.files.item(0).getAsDataURL();
- }
- return obj.value;
- }
- return obj.value;
- }
- }
- </script>
- </head>
- <body>
- <form name=form1 method=post enctype="multipart/form-data" action="<%=path%>/imgUpload">
- <div style="margin-left: 35%;margin-top: 20%">
- <table width="100%" border="0" align="center" cellpadding="0" cellspacing="0" >
- <tr>
- <td > 圖片上傳<font color='red'>*.gif,*.jpg,*.png,*.bmp</font></td>
- </tr>
- <tr>
- <td width="80%">
- <input type="file" name="imgFile" id="imgFile" maxlength="160" onchange="checkImgType(this);" width="300px"/>
- </td>
- </tr>
- </table>
- </div>
- </form>
- </body>
- </html>
</div>
2 ImgUploadServlet.java(圖片上傳處理類)
</div>
- import java.awt.image.BufferedImage;
- import java.io.File;
- import java.io.IOException;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import javax.imageio.ImageIO;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- public class ImgUploadServlet extends HttpServlet {
- private static final long serialVersionUID = 1L;
- public static final String IMGROOT = "/uploads/";
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- doPost(request,response);
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- String userWebAppPath = getWebAppPath();
- /**檢查是否有圖片上傳文件夾*/
- checkImageDir(userWebAppPath);
- /**圖片上傳的相對路徑*/
- String imgUploadPath = null;
- String imgWebAppPath = null;
- /**圖片后綴*/
- String imgFileExt = null;
- /**圖片名稱:以當前日期*/
- SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddhhmmss");
- String imgFileId = formatter.format(new Date());
- //圖片初始化高度與寬度
- String width = null;
- String height = null;
- int imgWidth = 0;
- int imgHeight = 0;
- try {
- com.jspsmart.upload.SmartUpload smartUpload = new com.jspsmart.upload.SmartUpload();
- smartUpload.initialize(getServletConfig(), request, response);
- smartUpload.upload();
- com.jspsmart.upload.Request rqest = smartUpload.getRequest();
- //指定圖片寬度和高度
- width = rqest.getParameter("width");
- if(null == width){
- width = "700";
- }
- height= rqest.getParameter("height");
- if(null == height){
- height = "600";
- }
- imgWidth = Integer.parseInt(width);
- imgHeight = Integer.parseInt(height);
- //文件個數
- int fileCounts = smartUpload.getFiles().getCount();
- for (int i = 0; i <fileCounts; i++) {
- com.jspsmart.upload.File myFile = smartUpload.getFiles().getFile(i);
- if (!myFile.isMissing()) {
- imgFileExt = myFile.getFileExt();
- //組裝圖片真實名稱
- imgFileId += i + System.currentTimeMillis() + "." + imgFileExt;
- //圖片生成路徑
- imgWebAppPath = userWebAppPath + imgFileId;
- //生成圖片文件
- myFile.saveAs(imgWebAppPath);
- //圖片的相對路徑
- imgUploadPath = IMGROOT + imgFileId;
- //檢查圖片大小
- BufferedImage src = ImageIO.read(new File(imgWebAppPath)); // 讀入文件
- int imgSrcWidth = src.getWidth(); // 得到源圖寬
- //重新指定大小
- imgWidth = imgSrcWidth > imgWidth ? imgWidth : imgSrcWidth;
- int imgSrcHeight = src.getHeight(); // 得到源圖長
- imgHeight = imgSrcHeight > imgHeight ? imgHeight : imgSrcHeight;
- //按照圖片的設置大小生成
- ImageCut.scale(imgWebAppPath, imgWebAppPath,imgWidth,imgHeight);
- File f = new File(imgWebAppPath);
- if(f.exists()){
- System.out.println("創建"+imgWidth+"*"+imgHeight+"圖片成功");
- }
- }
- }
- }catch(Exception ex){
- ex.printStackTrace();
- }
- String path = "/imgcrop.jsp?tag=0&oldImgPath="+imgUploadPath+"&imgFileExt="+imgFileExt+"&imgRoot="+IMGROOT+"&width="+imgWidth+"&height="+imgHeight;
- System.out.println("path: "+path);
- request.getRequestDispatcher(path).forward(request,response);
- }
- private String getWebAppPath(){
- String webAppPath = this.getServletContext().getRealPath("/");
- String userWebAppPath = webAppPath+IMGROOT;
- return userWebAppPath;
- }
- private void checkImageDir(String userWebAppPath) {
- File file = new File(userWebAppPath);
- if(!file.exists()){
- file.mkdir();
- }
- }
- }
</div>
3 imgcrop.jsp(圖片展現并剪切頁面)
</div>
- <%@ page language="java" pageEncoding="UTF-8"%>
- <%
- String path = request.getContextPath();
- String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
- %>
- <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- <base href="<%=basePath%>">
- <title>圖片剪輯</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">
- <link rel="stylesheet" href="styles/jquery.Jcrop.css" type="text/css" />
- <link rel="stylesheet" href="styles/demos.css" type="text/css" />
- <script src="scripts/jquery.min.js"></script>
- <script src="scripts/jquery.Jcrop.js"></script>
- </head>
- <body STYLE='OVERFLOW:SCROLL;OVERFLOW-X:HIDDEN;OVERFLOW-Y:HIDDEN'>
- <form name=form1 method=post action="<%=path%>/imgCrop">
- <table width="60%" border="0" align="center" cellpadding="0" cellspacing="0" >
- <tr>
- <td id="cropTd" style="display:none"><input type="button" value="剪切照片" id="cropButton"/></td>
- </tr>
- <tr>
- <td id="imgTd" style="width:${param.width}px;height:${param.height}px;" align="center" style="padding-top:5px;">
- <c:choose>
- <c:when test="${param.tag eq 0}">
- <img src="<%=path%>${param.oldImgPath}" id="imgCrop" name="imgCrop" border="0" />
- </c:when>
- <c:when test="${param.tag eq 1}">
- <img src="<%=path%>${param.imgName}" id="imgCrop" name="imgCrop" border="0" />
- </c:when>
- </c:choose>
- </td>
- </tr>
- <tr>
- <td>
- <label>X1 <input type="text" size="4" id="labelX" name="labelX" /></label>
- <label>Y1 <input type="text" size="4" id="labelY" name="labelY" /></label>
- <label>X2 <input type="text" size="4" id="labelX2" name="labelX2" /></label>
- <label>Y2 <input type="text" size="4" id="labelY2" name="labelY2" /></label>
- <label>W <input type="text" size="4" id="labelW" name="labelW" /></label>
- <label>H <input type="text" size="4" id="labelH" name="labelH" /></label>
- </td>
- </tr>
- <tr>
- <td colspan="2"><a href="index.jsp">返回上傳圖片</a></td>
- </tr>
- </table>
- <input type="hidden" id="x" name="x" />
- <input type="hidden" id="y" name="y" />
- <input type="hidden" id="x2" name="x2" />
- <input type="hidden" id="y2" name="y2" />
- <input type="hidden" id="w" name="w" />
- <input type="hidden" id="h" name="h" />
- <!-- 源圖片寬度和高度 -->
- <input type="hidden" id="width" name="width" value="${param.width}"/>
- <input type="hidden" id="height" name="height" value="${param.height}"/>
- <input type="hidden" id="oldImgPath" name="oldImgPath" value="${param.oldImgPath}"/>
- <input type="hidden" id="imgRoot" name="imgRoot" value="${param.imgRoot}"/>
- <input type="hidden" id="imgFileExt" name="imgFileExt" value="${param.imgFileExt}"/>
- </form>
- </body>
- </html>
- <script type="text/javascript">
- jQuery(document).ready(function(){
- jQuery('#imgCrop').Jcrop({
- onChange: showCoords,
- onSelect: showCoords
- });
- jQuery('#cropButton').click(function(){
- var x = jQuery("#x").val();
- var y = jQuery("#y").val();
- var w = jQuery("#w").val();
- var h = jQuery("#h").val();
- if(w == 0 || h == 0 ){
- alert("您還沒有選擇圖片的剪切區域,不能進行剪切圖片!");
- return;
- }
- alert("你要剪切圖片的X坐標: "+x + ",Y坐標: " + y + ",剪切圖片的寬度: " + w + ",高度:" + h );
- if(confirm("確定按照當前大小剪切圖片嗎")){
- document.form1.submit();
- }
- });
- });
- function showCoords(c)
- {
- jQuery('#x').val(c.x);
- jQuery('#y').val(c.y);
- jQuery('#x2').val(c.x2);
- jQuery('#y2').val(c.y2);
- jQuery('#w').val(c.w);
- jQuery('#h').val(c.h);
- jQuery('#labelX').val(c.x);
- jQuery('#labelY').val(c.y);
- jQuery('#labelX2').val(c.x2);
- jQuery('#labelY2').val(c.y2);
- jQuery('#labelW').val(c.w);
- jQuery('#labelH').val(c.h);
- //顯示剪切按鍵
- jQuery('#cropTd').css("display","");
- }
- </script>
</div>
4 ImgCropServlet.java(執行圖片剪切類)
</div>
- import java.io.File;
- import java.io.IOException;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- public class ImgCropServlet extends HttpServlet {
- private static final long serialVersionUID = 1L;
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- doPost(request, response);
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- System.out.println("x: " + request.getParameter("x") + "," + request.getParameter("y") + "," + request.getParameter("w") + "," + request.getParameter("h"));
- // 用戶經過剪輯后的圖片的大小
- Integer x = Integer.parseInt(request.getParameter("x"));
- Integer y = Integer.parseInt(request.getParameter("y"));
- Integer w = Integer.parseInt(request.getParameter("w"));
- Integer h = Integer.parseInt(request.getParameter("h"));
- //獲取原顯示圖片路徑
- String oldImgPath = request.getParameter("oldImgPath");
- //圖片后綴
- String imgFileExt = request.getParameter("imgFileExt");
- String imgRoot = request.getParameter("imgRoot");
- Integer width = Integer.parseInt(request.getParameter("width"));
- Integer height = Integer.parseInt(request.getParameter("height"));
- //WEB應用程序根路徑
- String webAppPath = getServletContext().getRealPath("/");
- /**圖片名稱:以當前日期*/
- SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddhhmmss");
- String imgFileId = formatter.format(new Date());
- String imgName = imgRoot + imgFileId + System.currentTimeMillis() + "." + imgFileExt;
- //組裝圖片真實名稱
- String createImgPath = webAppPath + imgName;
- //之前上傳的圖片路徑
- webAppPath += oldImgPath;
- System.out.println("原圖片路徑: " + webAppPath + ",新圖片路徑: " + createImgPath);
- //進行剪切圖片操作
- ImageCut.abscut(webAppPath, createImgPath, x,y,w, h);
- File f = new File(createImgPath);
- if(f.exists()){
- System.out.println("剪切圖片大小: "+w+"*"+h+"圖片成功!");
- }
- String path = "/imgcrop.jsp?tag=1&oldImgPath="+oldImgPath+"&imgFileExt="+imgFileExt+"&imgRoot="+imgRoot + "&imgName="+imgName+"&height=" + height + "&width=" + width;
- System.out.println("imgCrop: " + path);
- request.getRequestDispatcher(path).forward(request,response);
- }
- }
</div>
5 ImageCut.java(圖片剪切工具類)
</div>
- import java.io.*;
- import java.awt.*;
- import java.awt.image.*;
- import java.awt.Graphics;
- import java.awt.color.ColorSpace;
- import javax.imageio.ImageIO;
- public class ImageCut {
- /**
- * 圖像切割(改) *
- * @param srcImageFile 源圖像地址
- * @param dirImageFile 新圖像地址
- * @param x 目標切片起點x坐標
- * @param y 目標切片起點y坐標
- * @param destWidth 目標切片寬度
- * @param destHeight 目標切片高度
- */
- public static void abscut(String srcImageFile,String dirImageFile, 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);
- // 改進的想法:是否可用多線程加快切割速度
- // 四個參數分別為圖像起點坐標和寬高
- // 即: CropImageFilter(int x,int y,int width,int height)
- 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(dirImageFile));
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- /**
- * 縮放圖像
- *
- * @param srcImageFile 源圖像文件地址
- * @param result 縮放后的圖像地址
- * @param scale 縮放比例
- * @param flag 縮放選擇:true 放大; false 縮小;
- */
- public static void scale(String srcImageFile, String result, int scale,
- boolean flag) {
- try {
- BufferedImage src = ImageIO.read(new File(srcImageFile)); // 讀入文件
- int width = src.getWidth(); // 得到源圖寬
- int height = src.getHeight(); // 得到源圖長
- if (flag) {
- // 放大
- width = width * scale;
- height = height * scale;
- } else {
- // 縮小
- width = width / scale;
- height = height / scale;
- }
- Image image = src.getScaledInstance(width, height,Image.SCALE_DEFAULT);
- BufferedImage tag = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
- Graphics g = tag.getGraphics();
- g.drawImage(image, 0, 0, null); // 繪制縮小后的圖
- g.dispose();
- ImageIO.write(tag, "JPEG", new File(result));// 輸出到文件流
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- /**
- * 重新生成按指定寬度和高度的圖像
- * @param srcImageFile 源圖像文件地址
- * @param result 新的圖像地址
- * @param _width 設置新的圖像寬度
- * @param _height 設置新的圖像高度
- */
- public static void scale(String srcImageFile, String result, int _width,int _height) {
- scale(srcImageFile,result,_width,_height,0,0);
- }
- public static void scale(String srcImageFile, String result, int _width,int _height,int x,int y) {
- try {
- BufferedImage src = ImageIO.read(new File(srcImageFile)); // 讀入文件
- int width = src.getWidth(); // 得到源圖寬
- int height = src.getHeight(); // 得到源圖長
- if (width > _width) {
- width = _width;
- }
- if (height > _height) {
- height = _height;
- }
- Image image = src.getScaledInstance(width, height,Image.SCALE_DEFAULT);
- BufferedImage tag = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
- Graphics g = tag.getGraphics();
- g.drawImage(image, x, y, null); // 繪制縮小后的圖
- g.dispose();
- ImageIO.write(tag, "JPEG", new File(result));// 輸出到文件流
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- /**
- * 圖像類型轉換 GIF->JPG GIF->PNG PNG->JPG PNG->GIF(X)
- */
- public static void convert(String source, String result) {
- try {
- File f = new File(source);
- f.canRead();
- f.canWrite();
- BufferedImage src = ImageIO.read(f);
- ImageIO.write(src, "JPG", new File(result));
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- /**
- * 彩色轉為黑白
- *
- * @param source
- * @param result
- */
- public static void gray(String source, String result) {
- try {
- BufferedImage src = ImageIO.read(new File(source));
- ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
- ColorConvertOp op = new ColorConvertOp(cs, null);
- src = op.filter(src, null);
- ImageIO.write(src, "JPEG", new File(result));
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
</div>