jcrop 图片压缩剪切

jcrop实现图片剪裁

    现在一些图片上传都需要处理一下大小,特别是头像的上传,具体怎么裁剪呢?这里介绍一款好用的插件 jcrop

下载地址 里面有简单的 页面demo jcrop下载

官网API :http://code.ciaoca.com/jquery/jcrop/  官网的demo是php 的


下面我介绍一下java的裁剪

图片剪裁需要的步骤

1、先上传需要裁剪的图片

html代码如下:

  
  
  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <title>图片上传</title>
  6. <base target="_self">
  7. <link href="${base}/cms/css/file.css" rel="stylesheet" type="text/css" />
  8. <script type="text/javascript" charset="utf-8" src="${base}/js/frame/jquery-1.9.1.js"></script>
  9. <script src="${base}/js/frameNew/jquery.form.min.js" type="text/javascript"></script>
  10. <script type="text/javascript" src="${base}/artdialog/artDialog.js?skin=blue"></script>
  11. <script type="text/javascript" src="${base}/artdialog/plugins/iframeTools.js"></script>
  12. <script type="text/JavaScript">
  13. function imageChange(){
  14. $("#fm").submit();
  15. }
  16. function subForm(){
  17. var path = '${returnPath?if_exists}';
  18. if($("#file").val()==''&& path == ""){
  19. $("#ff").html("请您选择要上传的图片!");
  20. return;
  21. }
  22. art.dialog.data("imagepath",$("#returnPath").val());
  23. art.dialog.close();
  24. }
  25. </script>
  26. </head>
  27. <body>
  28. <div class="pop-up_box" id="div0">
  29. <div class="pop-up_bottom">
  30. <div class="mainright" style="width:570px; height:450px">
  31. <div class="pop_upload">
  32. <div class="upload_bar">
  33. <div><a href="#" class="active"><img src="${base}/cms/images/file/pop-up_20.gif" />上传图片</a></div>
  34. </div>
  35. <div class="upload_main2">
  36. <table width="100%" border="0" align="center" cellpadding="0" cellspacing="0" class="upload_table">
  37. <tr>
  38. <th width="11%">说明:</th>
  39. <td width="89%">每个图片允许大小2M,支持格式jpg/jpeg/png文件</td>
  40. </tr>
  41. </table>
  42. <div class="upload_imgtable">
  43. <form id="fm" action="${base}/uploadSerevice.action" method="post" enctype="multipart/form-data">
  44. <input type="hidden" id="entId" name="entId" value="${newsId?if_exists}">
  45. <input type = "hidden" id="returnPath" value="${returnPath?if_exists}"/>
  46. <div style="margin:12px 0 0 12px">
  47. <input id="file" type="file" name="file" class="upload_text" style="width:270px;height:20px;"onchange="imageChange()"/>
  48. </div>
  49. <div style="margin:12px 0 0 12px">
  50.  <font id ="ff"color="red">${msg?if_exists} </font>
  51. </div>
  52. </form>
  53. </div>
  54. <div style="margin:12px 0 0 12px" >
  55. <#if returnPath?exists>
  56. <#if '${returnPath?if_exists}'!="">
  57. <img id="imgLogo" src="${base}/${returnPath?if_exists}" style="border:none;" width="254" height="142"/>
  58. <#else>
  59. </#if>
  60. <#else>
  61. </#if>
  62. </div>
  63. <div class="tijiao"style="margin:20px 0 0 12px">
  64. <a href="#" onclick="subForm();" ><img src="${base}/images/tijiao.gif" width="82" height="35" /></a>    
  65. <a href="#" onclick="art.dialog.close();" ><img src="${base}/images/quxiao.gif" width="82" height="35" /></a></div>
  66. </div>
  67. </div>
  68. </div>
  69. </div>
  70. </div>
  71. </div>
  72. </body>
  73. </html>
选择图片后自动提交到action,action代码下面会讲到,这里使用的方法是: uploadSerevice()


2、展示上传的图片,然后进行需要裁剪的区域选择(提交图片后,跳转的页面,显示上一步上传的图片)


首先页面需要引用jcrop的js和css 以及初始化的一些function

引用:

 
 
  1. <link   rel="stylesheet" href="${base}/jcrop/css/jquery.Jcrop.css" type="text/css" />
  2. <script src="${base}/js/frame/jquery-17.1.min.js" type="text/javascript"></script>
  3. <script src="${base}/jcrop/js/jquery.Jcrop.js" type="text/javascript"></script>


比较常用的几个参数这里介绍一下:


aspectRatio 1 选框宽高比。说明:width/height;
boxWidth 508 画布宽度
boxHeight 284 画布高度



下面是我自己的一段js,和html,适用于自己的场景,需要的可以参考:

 
 
  1. <script type="text/javascript">
  2.    jQuery(function($){
  3.      var jcrop_api, boundx, boundy;
  4.      $('#target').Jcrop({
  5.        onChange: updatePreview,//调用的function  选框改变时的事件
  6.        onSelect: updatePreview,//调用的function  选框选定时的事件
  7.        aspectRatio: 254/142, //裁剪框的比例大小
  8.        boxWidth:300, //画布的宽
  9.        boxHeight:284,//画布的高
  10.      },function(){
  11.        // Use the API to get the real image size
  12.        var bounds = this.getBounds(); //获取图片实际尺寸,格式为:[w, h]
  13.        boundx = bounds[0];
  14.        boundy = bounds[1];
  15.        // Store the API in the jcrop_api variable
  16.        jcrop_api = this;
  17.        jcrop_api.animateTo([0,0,142,142]);//初始化裁剪框位置
  18.        
  19.      });
  20.      function updatePreview(c){
  21.        if (parseInt(c.w) > 0){
  22.     var rx = 127/ c.w;  //width
  23.         var ry = 71/ c.h;
  24.           $('#preview').css({
  25.            width: Math.round(rx * boundx) + 'px',
  26.            height: Math.round(ry * boundy) + 'px',
  27.            marginLeft: '-' + Math.round(rx * c.x) + 'px',
  28.            marginTop: '-' + Math.round(ry * c.y) + 'px'
  29.          });
  30.          
  31.          
  32.        }
  33.        $("#width").attr("value",c.w);//c.w 裁剪区域的宽
  34.     $("#height").attr("value",c.h);//c.h 裁剪区域的高
  35.    
  36.     $("#x").attr("value",c.x);//c.x 裁剪区域左上角顶点相对于图片左上角顶点的x坐标
  37.     $("#y").attr("value",c.y); //c.y 裁剪区域顶点的y坐标
  38.      };
  39.    });
  40.    
  41. function subForm(){
  42. $("#fm").submit();
  43. }
  44.  </script>


下面这段js 是我初始化页面从后台获取的原始图片,个人根据自己的需要进行设置

 
 
  1. <script type="text/JavaScript">
  2.                                        
  3. $(document).ready(function(){                                          
  4.     var img = (document.getElementById("image1").value).replace(/\\/g,'/');
  5.     document.getElementById("preview").src = img;
  6.     document.getElementById("target").src = img;
  7. });
  8. </script>


页面html

 
 
  1. <body>
  2.  <!--right开始-->
  3.  <form action="${base}/cutservicePic.action" method="post"id="fm">
  4.    <input type="hidden" name="entId" id="entId" value="${entId?if_exists}"/>
  5. <input type="hidden" name="image.x" id="x" value=""/>
  6. <input type="hidden" name="image.y" id="y" value=""/>
  7. <input type="hidden" name="image.width" id="width" value=""/>
  8. <input type="hidden" name="image.height" id="height" value=""/>
  9. <input type="hidden" name="pathPic" value="${pathPic?if_exists}"/>
  10.        <input type="hidden" id="image1" value="${pathPic?if_exists}"/>          <!--后台传过来的需要裁剪的页面地址-->
  11.    <table width="532" height="354" border="0" style="border:1px solid #ddd;">
  12.  <tr>
  13.    <td height="292" colspan="2"><a href="#">
  14.   <div class="tutu1" >
  15.     <img   src="" id="target" alt=""   />                                <!--后台传过来的需要裁剪的页面地址,当然自己测试时候可以直接使用本地文件-->
  16.   </div>
  17.    </td>
  18.    <td width="204">
  19.     <div class="you1"><strong>效果预览</strong> </div>
  20.     <div class="you2">请注意预览效果是否清晰 </div>
  21.    <div class="tutu2" style="width:127px;height:71px;overflow:hidden; solid gray;">
  22.     <img src="" id="preview"  />                          <!--后台传过来的需要裁剪的页面地址,当然自己测试时候可以直接使用本地文件-->
  23.    </div>
  24.    </td>
  25.  </tr>
  26. </table>
  27.    <div class="zuo">
  28.    <div class="tijiao">
  29.      <a href="#"  onclick="subForm();" ><img src="${base}/images/tijiao.gif" width="82" height="35" /></a>    
  30.      <a href="#"  onclick="art.dialog.close();" ><img src="${base}/images/quxiao.gif" width="82" height="35" /></a></div>
  31.    </div>
  32. </body>

效果图如下图:

左边的是 id为target 的图片  右边的是id为preview 的  图片地址都是一样的 ,左上角的是剪裁框;

需要预览不同大小的话继续添加preview1 等;就会出来两个预览框,当然还需要添加相应的js,这时候效果如下(下面是我做头像 高宽1:1时候的样子)





3、根据选择区域剪切成自己想要的图片,以java为例,php的看官网,官网有现成的demo;


在上面的js里面你会发现 你可以获取到你裁剪的图片的四个坐标;把这些坐标提交到后台:

我用的post提交,把这些从js 赋值给input隐藏域:也就是最上面html代码中的隐藏域 image.x  image.y这些值

提交到后台获取到坐标:



下面贴上整个action类


 
 
  1. package cn.fulong.omp.web.action.person;
  2. import java.awt.Color;
  3. import java.awt.Graphics;
  4. import java.awt.Image;
  5. import java.awt.image.BufferedImage;
  6. import java.awt.image.ConvolveOp;
  7. import java.awt.image.Kernel;
  8. import java.io.File;
  9. import java.io.FileOutputStream;
  10. import java.io.IOException;
  11. import java.sql.Timestamp;
  12. import javax.swing.ImageIcon;
  13. import org.apache.commons.io.FileUtils;
  14. import org.apache.commons.lang.StringUtils;
  15. import org.apache.struts2.ServletActionContext;
  16. import cn.fulong.frame.config.Platform;
  17. import cn.fulong.frame.transaction.BaseTransaction;
  18. import cn.fulong.frame.web.action.BaseAction;
  19. import cn.fulong.omp.dm.CommonOrganization;
  20. import com.sun.image.codec.jpeg.JPEGCodec;
  21. import com.sun.image.codec.jpeg.JPEGEncodeParam;
  22. import com.sun.image.codec.jpeg.JPEGImageEncoder;
  23. public class ImageCutAction extends BaseAction{
  24. /**
  25. * 上传的文件
  26. */
  27. private File file;
  28. private String entId;
  29. private String pathPic;
  30. private String fileFileName;
  31. private String msg;
  32. private String url;
  33. private OperateImage image;
  34. /**
  35. * 剪裁后的图片地址
  36. */
  37. private String returnPath;
  38. public String getReturnPath() {
  39. return returnPath;
  40. }
  41. public void setReturnPath(String returnPath) {
  42. this.returnPath = returnPath;
  43. }
  44. public OperateImage getImage() {
  45. return image;
  46. }
  47. public void setImage(OperateImage image) {
  48. this.image = image;
  49. }
  50. public String getUrl() {
  51. return url;
  52. }
  53. public void setUrl(String url) {
  54. this.url = url;
  55. }
  56. Timestamp currentTime = new Timestamp(System.currentTimeMillis());
  57. public String getEntId() {
  58. return entId;
  59. }
  60. public void setEntId(String entId) {
  61. this.entId = entId;
  62. }
  63. public String getPathPic() {
  64. return pathPic;
  65. }
  66. public void setPathPic(String pathPic) {
  67. this.pathPic = pathPic;
  68. }
  69. public String getFileFileName() {
  70. return fileFileName;
  71. }
  72. public void setFileFileName(String fileFileName) {
  73. this.fileFileName = fileFileName;
  74. }
  75. public String getMsg() {
  76. return msg;
  77. }
  78. public void setMsg(String msg) {
  79. this.msg = msg;
  80. }
  81. public File getFile() {
  82. return file;
  83. }
  84. public void setFile(File file) {
  85. this.file = file;
  86. }
  87. /**
  88. * 这里是一个图片的压缩方法,可以用可以不用,需要压缩的可以使用
  89. * @param originalFile  原始图片
  90. * @param resizedFile  压缩图片
  91. * @param newWidth  新的高度
  92. * @param quality  像素
  93. * @throws IOException
  94. */
  95. private  void resize(File originalFile, File resizedFile,int newWidth, float quality) throws IOException {
  96. if (quality > 1) {
  97. throw new IllegalArgumentException("Quality has to be between 0 and 1");
  98. }
  99. ImageIcon ii = new ImageIcon(originalFile.getCanonicalPath());
  100. Image i = ii.getImage();
  101. Image resizedImage = null;
  102. int iWidth = i.getWidth(null);
  103. int iHeight = i.getHeight(null);
  104. if (iWidth > iHeight) {
  105. resizedImage = i.getScaledInstance(newWidth, (newWidth * iHeight)/ iWidth, Image.SCALE_SMOOTH);
  106. } else {
  107. resizedImage = i.getScaledInstance((newWidth * iWidth) / iHeight,newWidth, Image.SCALE_SMOOTH);
  108. }
  109. // This code ensures that all the pixels in the image are loaded.
  110. Image temp = new ImageIcon(resizedImage).getImage();
  111. // Create the buffered image.
  112. BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null),
  113. temp.getHeight(null), BufferedImage.TYPE_INT_RGB);
  114. // Copy image to buffered image.
  115. Graphics g = bufferedImage.createGraphics();
  116. // Clear background and paint the image.
  117. g.setColor(Color.white);
  118. g.fillRect(0, 0, temp.getWidth(null), temp.getHeight(null));
  119. g.drawImage(temp, 0, 0, null);
  120. g.dispose();
  121. // Soften.
  122. float softenFactor = 0.05f;
  123. float[] softenArray = { 0, softenFactor, 0, softenFactor,1 - (softenFactor * 4), softenFactor, 0, softenFactor, 0 };
  124. Kernel kernel = new Kernel(3, 3, softenArray);
  125. ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
  126. bufferedImage = cOp.filter(bufferedImage, null);
  127. // Write the jpeg to a file.
  128. FileOutputStream out = new FileOutputStream(resizedFile);
  129. // Encodes image as a JPEG data stream
  130. JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
  131. JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bufferedImage);
  132. param.setQuality(quality, true);
  133. encoder.setJPEGEncodeParam(param);
  134. encoder.encode(bufferedImage);
  135. } // Example usage
  136. /**
  137. * 上传服务图片    这个类是上传原是图片的方法
  138. * @return
  139. */
  140. public String uploadSerevice() {
  141. url="/ueditor/executeSerevice.action?newsId="+entId;
  142. String extFileName = "";
  143. if ((file != null) && (file.length() > 0L)) {
  144.      int index = StringUtils.lastIndexOf(fileFileName, '.');
  145.      if (index == -1){
  146.        msg = "附件名称错误!";
  147.        return "success";
  148.      }
  149.      extFileName = StringUtils.substring(fileFileName, index + 1);
  150.      if ((!"jpg".equalsIgnoreCase(extFileName)) && (!"jpeg".equalsIgnoreCase(extFileName))&&
  151.      (!"png".equalsIgnoreCase(extFileName))&&(!"gif".equalsIgnoreCase(extFileName))){
  152.        msg = "文件类型不正确,必须为jpg/jpeg/png/gif文件!";
  153.        return "success";
  154.      }
  155.      if (this.file.length() > 1048576L*2){
  156.        msg = "文件太大,不能超过2M!";
  157.        return "success";
  158.      }
  159.  String separator = File.separator;
  160.        String rootpath = Platform.getInstance().getRealPath() ;//项目所在位置
  161.      String mypath = "file" + separator+"logo" + separator;//定义文件夹
  162.  //original
  163.  // 存入磁盘
  164.      String filename = "original_"+entId+"_"+currentTime.getTime()+ "." + extFileName.toLowerCase();//定义文件名称  //原图
  165.      String path= rootpath +separator+ mypath+filename;
  166.      String cutfilename = "original_cut_"+entId+"_"+currentTime.getTime()+ "." + extFileName.toLowerCase();//定义文件名称 //经过压缩的图片
  167.      String cutPath = rootpath +separator+ mypath+cutfilename;
  168.  System.out.println("---文件上传位置---"+path);
  169.        File destFile = new File(path);
  170.        File cutFile = new File(cutPath);
  171.        pathPic = mypath+filename;
  172.        //pathPic=mypath+cutfilename;
  173.      try {
  174.        FileUtils.copyFile(file, destFile);
  175.        // ImageHepler help = new ImageHepler();
  176.        //help.saveImageAsJpg(path, cutPath, 500, 500, true);
  177.        //resize(destFile, cutFile, 254, 1f); //需要压缩的 ,调用压缩方
  178.      }catch (Exception e) {
  179.        e.printStackTrace();
  180.        msg = "上传图片失败";
  181.        return "success";
  182.      }  
  183.  }
  184. return "uploadSerevice";
  185. }
  186. /**
  187. * 剪切服务产品图片
  188. * @return
  189. */
  190. public String cutservicePic() {
  191. String name = ServletActionContext.getServletContext().getRealPath(pathPic);
  192. image.setSrcpath(name);//原始文件
  193. int index = StringUtils.lastIndexOf(pathPic, '.');
  194. String extFileName = StringUtils.substring(pathPic, index + 1);
  195. String separator = File.separator;
  196.      String rootpath = Platform.getInstance().getRealPath() ;//项目所在位置
  197.    String mypath = "file" + separator+"logo" + separator;//定义文件夹
  198.    String filename = entId+"_"+currentTime.getTime()+"_1." + extFileName.toLowerCase();//定义文件名称 裁剪后的
  199.    String newPic = rootpath+separator+mypath+filename;
  200.    
  201.    String resizeFilename = entId+"_"+currentTime.getTime()+"." + extFileName.toLowerCase();//定义文件名称 裁剪后的 再次进行压缩的
  202.    String newResizePic = rootpath+separator+mypath+resizeFilename;
  203.   // returnPath = mypath+resizeFilename;  返回压缩过的图片
  204.    returnPath = mypath+filename;
  205.    System.out.println("-----剪裁图片地址-----"+newPic);
  206. image.setSubpath(newPic);//裁剪后的文件地址
  207. try {
  208. image.cut(); //执行裁剪操作  执行完后即可生成目标图在对应文件夹内。</span>
  209. File newFile = new File(newPic);
  210. File newResizeFile = new File(newResizePic);
  211. //resize(newFile, newResizeFile, 254, 1f);  //生成第二个压缩图片,需要压缩的使用
  212. } catch (IOException e) {
  213. e.printStackTrace();
  214. }
  215. url="/ueditor/executeSerevice.action?newsId="+entId;
  216. return "success";
  217. }
  218. }


OperateImage类

 
 
  1. package cn.fulong.omp.web.action.person;
  2. import java.awt.Rectangle;
  3. import java.awt.image.BufferedImage;
  4. import java.io.File;
  5. import java.io.FileInputStream;
  6. import java.io.IOException;
  7. import java.util.Iterator;
  8. import javax.imageio.ImageIO;
  9. import javax.imageio.ImageReadParam;
  10. import javax.imageio.ImageReader;
  11. import javax.imageio.stream.ImageInputStream;
  12. public class OperateImage {
  13. // ===源图片路径名称如:c:\1.jpg
  14. private String srcpath;
  15. // ===剪切图片存放路径名称.如:c:\2.jpg
  16. private String subpath;
  17. // ===剪切点x坐标
  18. private int x;
  19. private int y;
  20. // ===剪切点宽度
  21. private int width;
  22. private int height;  
  23. public String getSrcpath() {
  24. return srcpath;
  25. }
  26. public void setSrcpath(String srcpath) {
  27. this.srcpath = srcpath;
  28. }
  29. public String getSubpath() {
  30. return subpath;
  31. }
  32. public void setSubpath(String subpath) {
  33. this.subpath = subpath;
  34. }
  35. public int getX() {
  36. return x;
  37. }
  38. public void setX(int x) {
  39. this.x = x;
  40. }
  41. public int getY() {
  42. return y;
  43. }
  44. public void setY(int y) {
  45. this.y = y;
  46. }
  47. public int getWidth() {
  48. return width;
  49. }
  50. public void setWidth(int width) {
  51. this.width = width;
  52. }
  53. public int getHeight() {
  54. return height;
  55. }
  56. public void setHeight(int height) {
  57. this.height = height;
  58. }
  59. public OperateImage() {
  60. }
  61. /** 对图片裁剪,并把裁剪完的新图片保存 */
  62. public void cut() throws IOException {
  63. FileInputStream is = null;
  64. ImageInputStream iis = null;
  65. try {
  66. // 读取图片文件
  67. is = new FileInputStream(srcpath);
  68. /*
  69. * 返回包含所有当前已注册 ImageReader 的 Iterator,这些 ImageReader 声称能够解码指定格式。
  70. * 参数:formatName - 包含非正式格式名称 . (例如 "jpeg" 或 "tiff")等 。
  71. */
  72. Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName("jpg");
  73. ImageReader reader = it.next();
  74. // 获取图片流
  75. iis = ImageIO.createImageInputStream(is);
  76. /*
  77. * <p>iis:读取源.true:只向前搜索 </p>.将它标记为 ‘只向前搜索’。
  78. * 此设置意味着包含在输入源中的图像将只按顺序读取,可能允许 reader 避免缓存包含与以前已经读取的图像关联的数据的那些输入部分。
  79. */
  80. reader.setInput(iis, true);
  81. /*
  82. * <p>描述如何对流进行解码的类<p>.用于指定如何在输入时从 Java Image I/O
  83. * 框架的上下文中的流转换一幅图像或一组图像。用于特定图像格式的插件 将从其 ImageReader 实现的
  84. * getDefaultReadParam 方法中返回 ImageReadParam 的实例。
  85. */
  86. ImageReadParam param = reader.getDefaultReadParam();
  87. /*
  88. * 图片裁剪区域。Rectangle 指定了坐标空间中的一个区域,通过 Rectangle 对象
  89. * 的左上顶点的坐标(x,y)、宽度和高度可以定义这个区域。
  90. */
  91. Rectangle rect = new Rectangle(x, y, width, height);
  92. // 提供一个 BufferedImage,将其用作解码像素数据的目标。
  93. param.setSourceRegion(rect);
  94. /*
  95. * 使用所提供的 ImageReadParam 读取通过索引 imageIndex 指定的对象,并将 它作为一个完整的
  96. * BufferedImage 返回。
  97. */
  98. BufferedImage bi = reader.read(0, param);
  99. // 保存新图片
  100. ImageIO.write(bi, "jpg", new File(subpath));
  101. } finally {
  102. if (is != null)
  103. is.close();
  104. if (iis != null)
  105. iis.close();
  106. }
  107. }
  108. }


到这里就全部完成了。

可以自己到剪裁后文件夹内看到剪裁的图片;








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值