今天有業務需要制作用戶頭像的需求,在網上找了個可以裁剪大圖制作自己希望大小的圖片的方法(基于Struts2)。特此記錄一下。
不廢話,具體的步驟如下:
<1> 使用html標簽上傳需要裁剪的大圖。
<2> 在頁面呈現大圖,使用Jcrop(Jquery)對大圖進行裁剪,并且可以進行預覽。
<3> 選擇好截取部分之后發送數據給Action,在服務器端使用 Java API 對大圖進行裁剪。
<4> 保存大圖裁剪好的頭像到指定目錄,完成業務。
下面一步一步做:
第一步:使用html標簽上傳需要裁剪的大圖。
這一步說白了也就是使用Struts2自帶的FileUpload功能,把圖片進行上傳具體代碼如下:
html頁面:
<form id="ulform" action="uploadPic.action" enctype="multipart/form-data" method="post"> <input type="file" name="pic" id="file" value="選擇圖片" /> <input type="submit" value="點擊上傳" /> </form>
Struts2配置文件
<action name="uploadPic" class="com.luoxiao.tbms.user.action.UserAction" method="uploadPic"> <result name="success" type="redirect">changePic.jsp</result> <result name="error">changePic.jsp</result> </action>
根據配置點擊提交按鈕,會提交表單,把圖片以流的形式發送給 UserAction的uploadPic方法,該方法如下:
public class UserAction{ private File pic; //(在此省略 get 和 set 方法) private String picFileName; //(省略get和set方法, 該屬性Struts2會自動賦值為上傳文件的文件名) public String uploadPic() { String[] str = { ".jpg", ".jpeg", ".bmp", ".gif" }; // 獲取用戶登錄名 TbUser curruser = (TbUser) getValue(SCOPE_SESSION, "curruser"); // 限定文件大小是4MB if (pic == null || pic.length() > 4194304) { //文件過大 return "error"; } for (String s : str) { if (picFileName.endsWith(s)) { String realPath = ServletActionContext.getServletContext().getRealPath("/uploadpic");// 在tomcat中保存圖片的實際路徑 == "webRoot/uploadpic/" File saveFile = new File(new File(realPath), "新文件名.jpg"); // 在該實際路徑下實例化一個文件 // 判斷父目錄是否存在 if (!saveFile.getParentFile().exists()) { saveFile.getParentFile().mkdirs(); } try { // 執行文件上傳 // FileUtils 類名 org.apache.commons.io.FileUtils; // 是commons-io包中的,commons-fileupload 必須依賴 // commons-io包實現文件上次,實際上就是將一個文件轉換成流文件進行讀寫 FileUtils.copyFile(pic, saveFile); } catch (IOException e) { return "imageError"; } } } return "success"; } } 這樣就可以把用戶選擇的圖片上傳到tomcat的webRoot/uploadpic/文件夾下。 然后訪問頁面,頁面中就可以顯示出剛剛上傳的大圖了。代碼如下。
<div style="width: 500px; height: 500px;"> <img style="margin-top:20px;" src="../uploadpic/上傳文件名稱.jpg"/>" id="target" alt="" /> </div>
第一步完成。
第二步:使用Jcrop插件裁剪該圖片,并且在頁面中預覽。
Jcrop是一個基于JQuery的成熟的圖片裁剪的插件。如圖:

該插件使用比較簡單:
<1> 在裁剪圖片頁面中,引入兩個js文件,和1個Jcrop需要的css文件(Jcrop包中有,注意引入順序,先引入jquery):
<script src="../js/jquery-1.8.3.min.js" type="text/javascript"></script> <script src="../js/jquery.Jcrop.js" type="text/javascript"></script> <link rel="stylesheet" href="../css/jquery.Jcrop.css" type="text/css" />
<2> 在html頁面中按照Jcrop要求的格式編寫兩個img標簽,一個用作裁剪后的預覽,一個用作顯示大圖,代碼如下:
預覽: <div style="width:200px;height:200px;overflow:hidden; border:1px solid gray;"> <img id="preview" width="200px" height="200px" /> </div> 原圖: <img src="../uploadpic/上傳大圖.jpg" id="target" alt="" />
<3> 在該頁面中寫js代碼,使其可以裁剪圖片并且預覽:
<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){ $('#preview').css({ width: Math.round(<span style="color:#ff0000;">200 </span>/ c.w * boundx) + 'px', <span style="color:#ff0000;">//200 為預覽div的寬和高</span> height: Math.round(<span style="color:#ff0000;">200 </span>/ c.h * boundy) + 'px', marginLeft: '-' + Math.round(200 / c.w * c.x) + 'px', marginTop: '-' + Math.round(200 / 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坐標 } }; }); </script> 至此我們已經可以看到裁剪之后的樣子了,并且也可以得到裁剪區域的x,y,height,width屬性。
第三步:把截取的該區域的屬性傳遞給action,讓action根據所得屬性,利用javaAPI把原圖裁剪成小圖。
<1> 設置form表單與隱藏域表單組件,并且在裁剪的時候對該四個組件的value屬性賦值
<form action="cutPic.action" method="post"> 點擊 <input type="hidden" name="image.x" id="x"/> <input type="hidden" name="image.y" id="y"/> <input type="hidden" name="image.width" id="width"/> <input type="hidden" name="image.height" id="height"/> <input type="submit" value="確定" /> ,設置完成。 </form>
<2> 點擊確定,提交該表單,訪問action,配置如下:
<action name="cutPic" class="com.luoxiao.tbms.user.action.UserAction" method="cutPic"> <result name="success" type="redirectAction">../announcement/announcement_list.action</result> </action>
<3>Struts2帶著四個參數訪問UserAction,并且會自動給UserAction中的image屬性賦值,該image屬性為OperateImage的一個實例對象,該類為裁剪圖片類,代碼如下:
package com.luoxiao.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; public OperateImage() { } /** 對圖片裁剪,并把裁剪完的新圖片保存 */ public void cut() throws IOException { FileInputStream is = null; ImageInputStream iis = null; try { // 讀取圖片文件 is = new FileInputStream(srcpath); /* * 返回包含所有當前已注冊 ImageReader 的 Iterator,這些 ImageReader 聲稱能夠解碼指定格式。 * 參數:formatName - 包含非正式格式名稱 . (例如 "jpeg" 或 "tiff")等 。 */ Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName("jpg"); 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, "jpg", new File(subpath)); } finally { if (is != null) is.close(); if (iis != null) iis.close(); } } } <4> 給該類的實例的四個屬性 x,y,width,height賦值之后,訪問action中的cutPic方法,代碼如下:
public class UserAction extends BaseAction { private OperateImage image;(省略get set) private File pic; // 接收這個上傳的文件 private String picFileName; // Struts2提供的格式,在文件名后+FileName就是上傳文件的名字 /** * 裁剪頭像 */ public String cutPic(){ String name = ServletActionContext.getServletContext().getRealPath("/uploadpic/原圖名.jpg"); image.setSrcpath(name); image.setSubpath(ServletActionContext.getServletContext().getRealPath("/uploadpic/裁剪目標圖名.jpg")); try { image.cut(); //執行裁剪操作 執行完后即可生成目標圖在對應文件夾內。 } catch (IOException e) { e.printStackTrace(); } return "success"; } } 第四步:把截取好的頭像保存在具體文件夾下即可,裁剪過程完成。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。
新聞熱點
疑難解答