struts2+jsp+jquery+Jcrop實(shí)現(xiàn)圖片裁剪并上傳實(shí)例
今天有業(yè)務(wù)需要制作用戶頭像的需求,在網(wǎng)上找了個(gè)可以裁剪大圖制作自己希望大小的圖片的方法(基于Struts2)。特此記錄一下。
不廢話,具體的步驟如下:
<1> 使用html標(biāo)簽上傳需要裁剪的大圖。
<2> 在頁(yè)面呈現(xiàn)大圖,使用Jcrop(Jquery)對(duì)大圖進(jìn)行裁剪,并且可以進(jìn)行預(yù)覽。
<3> 選擇好截取部分之后發(fā)送數(shù)據(jù)給Action,在服務(wù)器端使用 Java API 對(duì)大圖進(jìn)行裁剪。
<4> 保存大圖裁剪好的頭像到指定目錄,完成業(yè)務(wù)。
下面一步一步做:
第一步:使用html標(biāo)簽上傳需要裁剪的大圖。
這一步說白了也就是使用Struts2自帶的FileUpload功能,把圖片進(jìn)行上傳具體代碼如下:
html頁(yè)面:
<form id="ulform" action="uploadPic.action" enctype="multipart/form-data" method="post"> <input type="file" name="pic" id="file" value="選擇圖片" /> <input type="submit" value="點(diǎn)擊上傳" /> </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>
根據(jù)配置點(diǎn)擊提交按鈕,會(huì)提交表單,把圖片以流的形式發(fā)送給 UserAction的uploadPic方法,該方法如下:
public class UserAction{ private File pic; //(在此省略 get 和 set 方法) private String picFileName; //(省略get和set方法, 該屬性Struts2會(huì)自動(dòng)賦值為上傳文件的文件名) 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中保存圖片的實(shí)際路徑 == "webRoot/uploadpic/" File saveFile = new File(new File(realPath), "新文件名.jpg"); // 在該實(shí)際路徑下實(shí)例化一個(gè)文件 // 判斷父目錄是否存在 if (!saveFile.getParentFile().exists()) { saveFile.getParentFile().mkdirs(); } try { // 執(zhí)行文件上傳 // FileUtils 類名 org.apache.commons.io.FileUtils; // 是commons-io包中的,commons-fileupload 必須依賴 // commons-io包實(shí)現(xiàn)文件上次,實(shí)際上就是將一個(gè)文件轉(zhuǎn)換成流文件進(jìn)行讀寫 FileUtils.copyFile(pic, saveFile); } catch (IOException e) { return "imageError"; } } } return "success"; } }
這樣就可以把用戶選擇的圖片上傳到tomcat的webRoot/uploadpic/文件夾下。 然后訪問頁(yè)面,頁(yè)面中就可以顯示出剛剛上傳的大圖了。代碼如下。
<div style="width: 500px; height: 500px;"> <img style="margin-top:20px;" src="../uploadpic/上傳文件名稱.jpg"/>" id="target" alt="" /> </div>
第一步完成。
第二步:使用Jcrop插件裁剪該圖片,并且在頁(yè)面中預(yù)覽。
Jcrop是一個(gè)基于JQuery的成熟的圖片裁剪的插件。如圖:
該插件使用比較簡(jiǎn)單:
<1> 在裁剪圖片頁(yè)面中,引入兩個(gè)js文件,和1個(gè)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頁(yè)面中按照J(rèn)crop要求的格式編寫兩個(gè)img標(biāo)簽,一個(gè)用作裁剪后的預(yù)覽,一個(gè)用作顯示大圖,代碼如下:
預(yù)覽: <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> 在該頁(yè)面中寫js代碼,使其可以裁剪圖片并且預(yù)覽:
<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; }); //裁剪過程中,每改變裁剪大小執(zhí)行該函數(shù) 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 為預(yù)覽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 裁剪區(qū)域的寬 $('#height').val(c.h); //c.h 裁剪區(qū)域的高 $('#x').val(c.x); //c.x 裁剪區(qū)域左上角頂點(diǎn)相對(duì)于圖片左上角頂點(diǎn)的x坐標(biāo) $('#y').val(c.y); //c.y 裁剪區(qū)域頂點(diǎn)的y坐標(biāo) } }; }); </script>
至此我們已經(jīng)可以看到裁剪之后的樣子了,并且也可以得到裁剪區(qū)域的x,y,height,width屬性。
第三步:把截取的該區(qū)域的屬性傳遞給action,讓action根據(jù)所得屬性,利用javaAPI把原圖裁剪成小圖。
<1> 設(shè)置form表單與隱藏域表單組件,并且在裁剪的時(shí)候?qū)υ撍膫€(gè)組件的value屬性賦值
<form action="cutPic.action" method="post"> 點(diǎn)擊 <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="確定" /> ,設(shè)置完成。 </form>
<2> 點(diǎn)擊確定,提交該表單,訪問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帶著四個(gè)參數(shù)訪問UserAction,并且會(huì)自動(dòng)給UserAction中的image屬性賦值,該image屬性為OperateImage的一個(gè)實(shí)例對(duì)象,該類為裁剪圖片類,代碼如下:
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; // ===剪切點(diǎn)x坐標(biāo) private int x; private int y; // ===剪切點(diǎn)寬度 private int width; private int height; public OperateImage() { } /** 對(duì)圖片裁剪,并把裁剪完的新圖片保存 */ public void cut() throws IOException { FileInputStream is = null; ImageInputStream iis = null; try { // 讀取圖片文件 is = new FileInputStream(srcpath); /* * 返回包含所有當(dāng)前已注冊(cè) ImageReader 的 Iterator,這些 ImageReader 聲稱能夠解碼指定格式。 * 參數(shù):formatName - 包含非正式格式名稱 . (例如 "jpeg" 或 "tiff")等 。 */ Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName("jpg"); ImageReader reader = it.next(); // 獲取圖片流 iis = ImageIO.createImageInputStream(is); /* * <p>iis:讀取源.true:只向前搜索 </p>.將它標(biāo)記為 ‘只向前搜索'。 * 此設(shè)置意味著包含在輸入源中的圖像將只按順序讀取,可能允許 reader 避免緩存包含與以前已經(jīng)讀取的圖像關(guān)聯(lián)的數(shù)據(jù)的那些輸入部分。 */ reader.setInput(iis, true); /* * <p>描述如何對(duì)流進(jìn)行解碼的類<p>.用于指定如何在輸入時(shí)從 Java Image I/O * 框架的上下文中的流轉(zhuǎn)換一幅圖像或一組圖像。用于特定圖像格式的插件 將從其 ImageReader 實(shí)現(xiàn)的 * getDefaultReadParam 方法中返回 ImageReadParam 的實(shí)例。 */ ImageReadParam param = reader.getDefaultReadParam(); /* * 圖片裁剪區(qū)域。Rectangle 指定了坐標(biāo)空間中的一個(gè)區(qū)域,通過 Rectangle 對(duì)象 * 的左上頂點(diǎn)的坐標(biāo)(x,y)、寬度和高度可以定義這個(gè)區(qū)域。 */ Rectangle rect = new Rectangle(x, y, width, height); // 提供一個(gè) BufferedImage,將其用作解碼像素?cái)?shù)據(jù)的目標(biāo)。 param.setSourceRegion(rect); /* * 使用所提供的 ImageReadParam 讀取通過索引 imageIndex 指定的對(duì)象,并將 它作為一個(gè)完整的 * 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> 給該類的實(shí)例的四個(gè)屬性 x,y,width,height賦值之后,訪問action中的cutPic方法,代碼如下:
public class UserAction extends BaseAction { private OperateImage image;(省略get set) private File pic; // 接收這個(gè)上傳的文件 private String picFileName; // Struts2提供的格式,在文件名后+FileName就是上傳文件的名字 /** * 裁剪頭像 */ public String cutPic(){ String name = ServletActionContext.getServletContext().getRealPath("/uploadpic/原圖名.jpg"); image.setSrcpath(name); image.setSubpath(ServletActionContext.getServletContext().getRealPath("/uploadpic/裁剪目標(biāo)圖名.jpg")); try { image.cut(); //執(zhí)行裁剪操作 執(zhí)行完后即可生成目標(biāo)圖在對(duì)應(yīng)文件夾內(nèi)。 } catch (IOException e) { e.printStackTrace(); } return "success"; } }
第四步:把截取好的頭像保存在具體文件夾下即可,裁剪過程完成。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- jQuery插件ImgAreaSelect實(shí)現(xiàn)頭像上傳預(yù)覽和裁剪功能實(shí)例講解一
- 利用jQuery插件imgAreaSelect實(shí)現(xiàn)圖片上傳裁剪(同步顯示圖像位置信息)
- 利用jQuery插件imgAreaSelect實(shí)現(xiàn)圖片上傳裁剪(放大縮?。?/a>
- jquery.Jcrop結(jié)合JAVA后臺(tái)實(shí)現(xiàn)圖片裁剪上傳實(shí)例
- jQuery實(shí)現(xiàn)圖片上傳和裁剪插件Croppie
- jQuery插件jcrop+Fileapi完美實(shí)現(xiàn)圖片上傳+裁剪+預(yù)覽的代碼分享
- jQuery+PHP實(shí)現(xiàn)上傳裁剪圖片
相關(guān)文章
Spring + Mybatis 項(xiàng)目實(shí)現(xiàn)動(dòng)態(tài)切換數(shù)據(jù)源實(shí)例詳解
這篇文章主要介紹了Spring + Mybatis 項(xiàng)目實(shí)現(xiàn)動(dòng)態(tài)切換數(shù)據(jù)源的相關(guān)資料,需要的朋友參考下吧2017-04-0495%的Java程序員人都用不好Synchronized詳解
這篇文章主要為大家介紹了95%的Java程序員人都用不好Synchronized詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03JUC三大輔助類CountDownLatch、CyclicBarrier和Semaphore詳解
這篇文章主要介紹了JUC三大輔助類CountDownLatch、CyclicBarrier和Semaphore詳解,CountDownLatch 類可以設(shè)置一個(gè)計(jì)數(shù)器,然后通過 countDown 方法來進(jìn)行 減 1 的操作,使用 await 方法等待計(jì)數(shù)器不大于 0,然后繼續(xù)執(zhí)行 await 方法 之后的語(yǔ)句,需要的朋友可以參考下2024-01-01如何解決Maven打包時(shí)每次都出現(xiàn)Download maven-metadata.xml卡住問題
這篇文章主要介紹了如何解決Maven打包時(shí)每次都出現(xiàn)Download maven-metadata.xml卡住問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05Java實(shí)現(xiàn)升級(jí)版布谷鳥闖關(guān)游戲的示例代碼
升級(jí)版布谷鳥闖關(guān)游戲是一個(gè)基于java的布谷鳥闖關(guān)游戲,鼠標(biāo)左鍵點(diǎn)擊控制鳥的位置穿過管道間的縫隙。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-02-02Spring Boot自定義Banner實(shí)現(xiàn)代碼
這篇文章主要介紹了Spring Boot自定義Banner實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01