jquery.Jcrop結(jié)合JAVA后臺實現(xiàn)圖片裁剪上傳實例
本文介紹了頭像裁剪上傳功能,用到的技術(shù)有 jQuery,springmvc,裁剪插件用的是jcrop(中間遇到很多坑,最終跨越)。
圖片上傳步驟:
1.用戶選擇圖片
2.將圖片傳入后臺:用戶選擇圖片的時候選擇的是各種各樣的,但是我們的網(wǎng)頁顯示圖片大小是有限的,所以我們就要在用戶選擇圖片之后將圖片添加到后臺進行壓縮,壓縮成我們想要的大小,之后再顯示到頁面才好
3.利用jcrop裁剪工具對圖片進行裁剪并且實時預(yù)覽
4.點擊確定按鈕將裁剪用到的參數(shù)傳入后臺,后臺圖片進行剪切,之后縮放成我們需要的格式
5.最后將圖片路徑傳到前臺進行展示
前臺頁面代碼為:
<script src="js-jcrop/jquery.min.js"></script>
<script src="js-jcrop/jquery.Jcrop.js"></script>
<script src="js/jquery-form.js"></script>
<link rel="stylesheet" href="../css/jquery.Jcrop.css" type="text/css" />
<style type="text/css">
/* 控制預(yù)覽區(qū)域大小*/
#preview-pane .preview-container {
width: 110px;
height: 110px;
overflow: hidden;
}
#targetDiv{
width: 400px;
height: 400px;
background-color:#f7fdff;
}
</style>
<dl class="dialogBox D_uploadLogo">
<dt class="dialogHeader">
<span class="title">頭像上傳</span>
</dt>
<dd class="dialogBody">
<dl class="bisinessLogo">
<dt class="title">預(yù)覽</dt>
<dd class="img">
<div id="preview-pane">
<div class="preview-container">
<img src="" id="target2" class="jcrop-preview" alt="未選擇圖片" />
</div>
</div>
</dd>
<dd class="tc">尺寸:110*110px</dd>
</dl>
<dl class="bisinessInfo">
<dt class="btnBox02">
<form id="fileUp" action="/file/img/upload" method="post" enctype="multipart/form-data" target="ifm">
<a class="btnGray" href="javascript:;">
<span class="text" id="format">選擇圖片</span>
<b class="bgR"></b>
<input type="file" id="file_upload" class="inputFile" name="userphoto"/>
<input type="hidden" id="w" name="w"/>
<input type="hidden" id="h" name="h"/>
<input type="hidden" id="x" name="x"/>
<input type="hidden" id="y" name="y"/>
</a>
</form>
</dt>
<dd class="info">
請從本地選擇一張照片,支持jpg,png格式 <span id="msg"></span>
<div id="targetDiv">
<img src="" id="target" width="400" height="400" alt="未選擇圖片"/>
</div>
</dd>
</dl>
</dd>
<input type="hidden" id="filePathInput" value=""/>
<dd class="dialogBottom">
<a class="btnBlue btn_confirm" href="javascript:;" onclick="photoSummit();"><span class="text">確定</span><b class="bgR"></b></a>
<a class="btnGray btn_cancel" href="javascript:;" onclick="hideDialog();"><span class="text">取消</span><b class="bgR"></b></a>
</dd>
</dl>
1.選擇圖片
<img src="" id="target" width="400" height="400" alt="未選擇圖片"/>
2.提交:首先大家知道文件上傳的時候用到的標簽為:<input type="file"/> 但是有時候我們需要用ajax提交文件并且異步提交,我們?nèi)绻怯胒orm表單提交的話就不是異步,這樣我們回到頁面就刷新頁面,非常的不方便,但是現(xiàn)在ajax還不能支持文件提交的方式,這時候我們就用到了jquery-form.js,這個文件支持我們用ajax提交文件,代碼為:
$("#fileUp").<span style="color:#ff0000;">ajaxSubmit</span>({
type: "POST",
url:"/file/img/upload",
dataType: "json",
contentType:"application/json",
success: function(parameter){
$("#target2").attr('src','/upload/'+parameter.fileName);
$("#filePathInput").val('/upload/'+parameter.fileName);
if($("#format").text()=="重新上傳"){
jcrop_api.destroy()
}
$("#format").text("重新上傳");
//啟動jcrop支持
openJcrop('/upload/'+parameter.fileName);
},
error : function(data) {
alert("ajax傳輸發(fā)生錯誤?。。?);
}
});
這樣就能將文件用ajax的方式提交到后臺,注意這里用的是ajaxSubmit,這個方法對應(yīng)jquery-form.js,后臺代碼為:
package com.quanshi.ums.gate.view.rest.controllers;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
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.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.quanshi.ums.gate.persistence.entities.Parameters;
import com.quanshi.ums.gate.view.rest.ImgEditor;
/**
* 圖像上傳和修改相關(guān)類
* @author kunpeng.zhao
*
*/
@Controller
@RequestMapping(value="/file")
public class FileEditorController {
<span style="white-space:pre"> </span>ImgEditor imgEditor = new ImgEditor();
<span style="white-space:pre"> </span>public String filePathFinal = "";
<span style="white-space:pre"> </span>private Logger logger = LoggerFactory.getLogger(FileEditorController.class);
<span style="white-space:pre"> </span>@RequestMapping(value="/img/cutandscale",method=RequestMethod.POST)
<span style="white-space:pre"> </span>public @ResponseBody int cutAndscaleimg(
<span style="white-space:pre"> </span>@RequestParam("w") int w,
<span style="white-space:pre"> </span>@RequestParam("h") int h,
<span style="white-space:pre"> </span>@RequestParam("x") int x,
<span style="white-space:pre"> </span>@RequestParam("y") int y
<span style="white-space:pre"> </span>){
<span style="white-space:pre"> </span>imgEditor.cut(filePathFinal,filePathFinal,x,y,w,h);
<span style="white-space:pre"> </span>imgEditor.scale(filePathFinal, filePathFinal, 110, 110, false);
<span style="white-space:pre"> </span>return 1;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>
@RequestMapping(value="/img/upload",method=RequestMethod.POST)
public @ResponseBody Parameters addImage(
<span style="white-space:pre"> </span>@RequestParam("userphoto") MultipartFile file,
<span style="white-space:pre"> </span>HttpServletRequest request,
<span style="white-space:pre"> </span>HttpServletResponse response,
<span style="white-space:pre"> </span>HttpSession session
<span style="white-space:pre"> </span>){
<span style="white-space:pre"> </span>String filePath = "";
<span style="white-space:pre"> </span>try {
<span style="white-space:pre"> </span>//上傳原圖
<span style="white-space:pre"> </span>filePath = imgEditor.uploadFile(file, request,session);
<span style="white-space:pre"> </span>filePathFinal = filePath;
<span style="white-space:pre"> </span>//將圖片壓縮成指定大小
<span style="white-space:pre"> </span>imgEditor.zoomImage(filePath,filePath,400,400);
<span style="white-space:pre"> </span>} catch (IOException e) {
<span style="white-space:pre"> </span>e.printStackTrace();
<span style="white-space:pre"> </span>}
logger.info("filePath:" + filePath);
Parameters parameter = new Parameters();
parameter.setFileName(imgEditor.getFileName(file,request,session));
<span style="white-space:pre"> </span>return parameter;
}
}
我在這規(guī)定圖片在前臺展示的大小為400*400,用到的圖片裁剪壓縮等的工具類為:
package com.quanshi.ums.gate.view.rest;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.multipart.MultipartFile;
public class ImgEditor {
/**
* 改變圖片尺寸
* @param srcFileName 源圖片路徑
* @param tagFileName 目的圖片路徑
* @param width 修改后的寬度
* @param height 修改后的高度
*/
public void zoomImage(String srcFileName,String tagFileName,int width,int height){
try {
BufferedImage bi = ImageIO.read(new File(srcFileName));
BufferedImage tag=new BufferedImage(width,height, BufferedImage.TYPE_INT_RGB);
tag.getGraphics().drawImage(bi, 0, 0, width, height, null);
ImageIO.write(tag, "jpg", new File(tagFileName));//畫圖
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 縮放圖像(按高度和寬度縮放)
* @param srcImageFile 源圖像文件地址
* @param result 縮放后的圖像地址
* @param height 縮放后的高度
* @param width 縮放后的寬度
* @param bb 比例不對時是否需要補白:true為補白; false為不補白;
*/
public void scale(String srcImageFile, String result, int height, int width, boolean bb) {
try {
double ratio = 0.0; // 縮放比例
File f = new File(srcImageFile);
BufferedImage bi = ImageIO.read(f);
Image itemp = bi.getScaledInstance(width, height, bi.SCALE_SMOOTH);
// 計算比例
if ((bi.getHeight() > height) || (bi.getWidth() > width)) {
if (bi.getHeight() > bi.getWidth()) {
ratio = (new Integer(height)).doubleValue()
/ bi.getHeight();
} else {
ratio = (new Integer(width)).doubleValue() / bi.getWidth();
}
AffineTransformOp op = new AffineTransformOp(AffineTransform
.getScaleInstance(ratio, ratio), null);
itemp = op.filter(bi, null);
}
if (bb) {//補白
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
g.setColor(Color.white);
g.fillRect(0, 0, width, height);
if (width == itemp.getWidth(null))
g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2,
itemp.getWidth(null), itemp.getHeight(null),
Color.white, null);
else
g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0,
itemp.getWidth(null), itemp.getHeight(null),
Color.white, null);
g.dispose();
itemp = image;
}
ImageIO.write((BufferedImage) itemp, "JPEG", new File(result));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 圖像切割(按指定起點坐標和寬高切割)
* @param srcImageFile 源圖像地址
* @param result 切片后的圖像地址
* @param x 目標切片起點坐標X
* @param y 目標切片起點坐標Y
* @param width 目標切片寬度
* @param height 目標切片高度
*/
public void cut(String srcImageFile, String result,
int x, int y, int width, int height) {
try {
// 讀取源圖像
BufferedImage bi = ImageIO.read(new File(srcImageFile));
int srcWidth = bi.getHeight(); // 源圖寬度
int srcHeight = bi.getWidth(); // 源圖高度
if (srcWidth > 0 && srcHeight > 0) {
Image image = bi.getScaledInstance(srcWidth, srcHeight,
Image.SCALE_DEFAULT);
// 四個參數(shù)分別為圖像起點坐標和寬高
// 即: CropImageFilter(int x,int y,int width,int height)
ImageFilter cropFilter = new CropImageFilter(x, y, width, height);
Image img = Toolkit.getDefaultToolkit().createImage(
new FilteredImageSource(image.getSource(),
cropFilter));
BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = tag.getGraphics();
g.drawImage(img, 0, 0, width, height, null); // 繪制切割后的圖
g.dispose();
// 輸出為文件
ImageIO.write(tag, "JPEG", new File(result));
}
} catch (Exception e) {
e.printStackTrace();
}
}
//獲得文件名字
public String getFileName(MultipartFile file, HttpServletRequest request,HttpSession session){
String FILE_PATH = session.getServletContext().getRealPath("/") + "upload";
String fileName = file.getOriginalFilename();
String[] suffixNameArr = fileName.split("\\.");
String suffixName = suffixNameArr[suffixNameArr.length-1];
String userName = SecurityContextHolder.getContext().getAuthentication().getName();
return getTime() + userName+"."+suffixName;
}
//文件上傳,返回文件路徑
public String uploadFile(MultipartFile file, HttpServletRequest request,HttpSession session) throws IOException {
String FILE_PATH = session.getServletContext().getRealPath("/") + "upload";
String fileName = getFileName(file,request,session);
File tempFile = new File(FILE_PATH, fileName);
if (!tempFile.getParentFile().exists()) {
tempFile.getParentFile().mkdir();
}
if (!tempFile.exists()) {
tempFile.createNewFile();
}
file.transferTo(tempFile); //將上傳文件寫到服務(wù)器上指定的文件。
return FILE_PATH + "\\" + tempFile.getName();
}
/* public static File getFile(String fileName) {
return new File(FILE_PATH, fileName);
} */
public String getTime(){
Date date = new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");//設(shè)置日期格式
String nowTime = df.format(date).toString();
return nowTime;
}
}
這樣就將圖片要裁剪的圖片路徑返回頁面展示
3.之后就是圖片裁剪了,圖片裁剪功能我找了好多插件,最后鎖定jcrop,也是因為它的demo打動了我(太好看了),之后就是導(dǎo)入文件,在我這里,我在頁面接收后臺返回來的圖片路徑之后啟用jcrop,也就是openJcrop()方法,這樣就可以加載jcrop插件了,具體大家想進一步了解這個裁剪工具,請到官網(wǎng)細細的研究,我就不再做過多的談?wù)摿恕?br />
大家注意,在這里有個大坑,真的是大坑,就是重新選擇圖片的時候,被jcrop加載過的img的src是不能被修改的,這個當(dāng)初卡了我好長時間,被jcrop加載一次jcrop就會生成一個自己的編輯對象(我自己的理解),這時候就和原來的img沒有關(guān)系了,直到最后細細研究api才找到了一個方法,唯一的方法就是將這個jcrop銷毀,就是jcrop_api.destroy(),這個有很大的學(xué)問,我就提示一點,就是將jcrop_api聲明為全局變量,下面貼出js代碼(和上邊的html是在一個文件下):
<script type="text/javascript">
$(function(){
var jcrop_api;
});
$("#file_upload").change(function() {
$("#msg").text('');
var oFile = $(this)[0].files[0];
//判斷上傳文件大小
if (oFile.size > 1*1024*1024) {
$("#msg").text('你選擇了太大的文件,請選擇一個1M以下的圖像文件').css('color','red');
$(this).val("");
return;
}
//判斷類型
var filepath=$(this).val();
var extStart=filepath.lastIndexOf(".");
var ext=filepath.substring(extStart,filepath.length).toUpperCase();
if(ext!=".JPEG"&&ext!=".PNG"&&ext!=".JPG"){
$("#msg").text('請選擇一個有效的圖像文件(jpg,png是允許的)').css('color','red');
$(this).val("");
return;
}
$("#fileUp").ajaxSubmit({
type: "POST",
url:"/file/img/upload",
dataType: "json",
contentType:"application/json",
success: function(parameter){
$("#target2").attr('src','/upload/'+parameter.fileName);
$("#filePathInput").val('/upload/'+parameter.fileName);
if($("#format").text()=="重新上傳"){
jcrop_api.destroy()
}
$("#format").text("重新上傳");
//啟動jcrop支持
openJcrop('/upload/'+parameter.fileName);
},
error : function(data) {
alert("ajax傳輸發(fā)生錯誤!?。?);
}
});
});
function photoSummit(){
//alert($("#w").val()+","+$("#h").val()+","+$("#x").val()+","+$("#y").val());
//$("#fileUp").attr("action", "/file/img/upload").submit();
if($("#w").val()>0 && $("#h").val()>0){
$("#fileUp").ajaxSubmit({
type: "POST",
url:"/file/img/cutandscale",
dataType: "json",
contentType:"application/json",
success: function(data){
$("#msg").text('上傳頭像成功?。?!').css('color','red');
//alert($("#filePathInput").val());
window.parent.back($("#filePathInput").val());
},
error : function(data) {
alert("ajax傳輸發(fā)生錯誤!??!");
}
});
}else{
$("#msg").text('請用鼠標截取圖片').css('color','red');
}
}
//啟動jcrop
function openJcrop(imgPath){
//啟動jcrop支持
var boundx,boundy,
xsize = $('#preview-pane .preview-container').width(),
ysize = $('#preview-pane .preview-container').height();
$('#target').Jcrop({
minSize: [110, 110],
onChange: updatePreview,
onSelect: updatePreview,
aspectRatio: xsize / ysize
},function(){
// Use the API to get the real image size
var bounds = this.getBounds();
boundx = bounds[0];
boundy = bounds[1];
jcrop_api = this;
});
jcrop_api.setImage(imgPath);
function updatePreview(c)
{
if (parseInt(c.w) > 0)
{
var rx = xsize / c.w;
var ry = ysize / c.h;
$('#preview-pane .preview-container img').css({
width: Math.round(rx * boundx) + 'px',
height: Math.round(ry * boundy) + 'px',
marginLeft: '-' + Math.round(rx * c.x) + 'px',
marginTop: '-' + Math.round(ry * c.y) + 'px'
});
$("#w").val(c.w);
$("#h").val(c.h);
$("#x").val(c.x);
$("#y").val(c.y);
}
};
}
</script>
這樣我們就完成了編輯功能,之后我們點擊提交就會將w,h,x,y參數(shù)傳到后臺。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Easyui Datagrid自定義按鈕列(最后面的操作列)
做項目的時候因為需求,要在表格的最后添加一列操作列,easyUI貌似沒有提供這種功能,下面我們來自定義按鈕列,具體實現(xiàn)代碼,大家參考下本文吧2017-07-07
jQuery下通過replace字符串替換實現(xiàn)大小圖片切換
實現(xiàn)的效果有點類似于Google picasa相冊不同尺寸圖片的切換效果。本實例通過文字大小(font-size)控制圖片尺寸的做法是跟Google學(xué)習(xí)的,但是jQuery代碼是根據(jù)效果自己想出來的,邏輯很簡單,沒有什么精妙之處2012-05-05
JavaScript實現(xiàn)的彈出遮罩層特效經(jīng)典示例【基于jQuery】
這篇文章主要介紹了JavaScript實現(xiàn)的彈出遮罩層特效,結(jié)合實例形式分析了基于jQuery實現(xiàn)的頁面元素與屬性動態(tài)操作相關(guān)使用技巧,需要的朋友可以參考下2019-07-07
jquery中使用$(#form).submit()重寫提交表單無效原因分析及解決
jqeury的validationEngine做ajax校驗,當(dāng)表單中的最后一個字段需要做ajax驗證,在字段輸入完畢后點擊回車提交表單時不起作用,接下來為大家介紹下解決方法感興趣的各位可以參考下哈2013-03-03
利用jQuery設(shè)計一個簡單的web音樂播放器的實例分享
這篇文章主要介紹了利用jQuery設(shè)計一個簡單的web音樂播放器的實例分享,包括PHP后臺和從MySQL中讀取曲目等基本功能的實現(xiàn),需要的朋友可以參考下2016-03-03
jQuery實現(xiàn)遍歷XML節(jié)點和屬性的方法示例
這篇文章主要介紹了jQuery實現(xiàn)遍歷XML節(jié)點和屬性的方法,涉及jQuery針對xml文件的加載、節(jié)點遍歷等相關(guān)操作技巧,需要的朋友可以參考下2018-04-04

