java 使用Jcrop 實現影象剪裁功能
阿新 • • 發佈:2019-02-16
1. 首先,頁面上先引入jquery.js 、jquery.Jcrop.js、jquery.Jcrop.css 這三個檔案 然後做好頁面上的配置、設計。在此只貼上剪裁區域設計程式碼
<input id="photo-input" name ="formInfo.photo" hidden="hidden"> <div class="col-lg-10" style="margin-left:60px;"> <div class="form-group"> <input id="input-1" name="photo" class="file" type="file" accept="image/*" width="90%" > </div> </div><br/><br/> <div class="form-group" style="margin-bottom:20px;margin-top:20px;"> <div class="col-lg-6" style="margin-left:40px;"> <img src="" id="target" style="max-width:400px;max-height:300px;"/> <div id="co" style="margin-top:5px;display:none;"> <label>X1 <input type="text" size="4" id="x1" name="formInfo.x1" /></label> <label>Y1 <input type="text" size="4" id="y1" name="formInfo.y2" /></label> <label>W <input type="text" size="4" id="w" name="formInfo.w" /></label> <label>H <input type="text" size="4" id="h" name="formInfo.h" /></label> </div> </div> <div class="col-lg-4" style="margin-left:20px;"> <div id="preview_box" style="width:215px;height:150px;overflow:hidden;margin-left:5px;"> <img src="" id="preview" name="formInfo.preview"/> </div> </div> </div>
<script type="java/script>
var jcrop_api; //建立全域性變數 控制jcrop api和圖片大小 var ramax = Math.random(); var random = "?tmp="+ramax+""; $('#input-1').fileinput('refresh',{initialPreview: []}) .change(function(event) { $('#input-1').fileinput('upload'); }) .on('filepreupload', function(event, data, previewId, index) { $('#change_class_btn').attr("disabled","disabled"); }) .on('fileuploaded', function(event, data, previewId, index) { $('#change_class_btn').removeAttr("disabled"); var response = data.response; if(response.code == -1){ jAlert('圖片上傳失敗!', '提示'); }else{ $('#photo-input').val(response.result); $('#target').attr('src',response.result+random); $('#preview').attr('src',response.result+random); var $preview = $('#preview'); $('#target').Jcrop({ onChange: showPreview, //選框改變時的事件 onSelect: showPreview, //選框選定時的事件 onRelease: hidePreview, //取消選框時的事件 aspectRatio: 215/150, //選框寬高比 setSelect: [ 0, 0, 200, 100 ] //設定預設選區 },function(){ jcrop_api = this; }); var $preview = $('#preview'); //簡單的事件處理程式,響應自onChange,onSelect事件 function showPreview(coords){ $('#x1').val(coords.x); $('#y1').val(coords.y); $('#w').val(coords.w); $('#h').val(coords.h); if (parseInt(coords.w) > 0){ var prebox_w = $('#preview_box').width(); //獲取顯示預覽區域圖層的寬度 var prebox_h = $('#preview_box').height(); //獲取顯示預覽區域圖層的高度 //計算預覽區域圖片縮放的比例,通過計算顯示區域的寬度(與高度)與剪裁的寬度(與高度)之比得到 var rx = prebox_w / coords.w; var ry = prebox_h / coords.h; var img_w = $("#target").width(); var img_h = $("#target").height(); //設定預覽區域層邊框樣式 $("#preview_box").css("border","1px solid #CDCDCD"); //通過比例值控制圖片的樣式與顯示 $preview.css({ width: Math.round(rx * img_w) + 'px', //預覽圖片寬度為計算比例值與原圖片寬度的乘積 height: Math.round(ry * img_h) + 'px', //預覽圖片高度為計算比例值與原圖片高度的乘積 marginLeft: '-' + Math.round(rx * coords.x) + 'px', marginTop: '-' + Math.round(ry * coords.y) + 'px' }).show(); } //if } function hidePreview(){ $preview.stop().fadeOut('fast'); } } //else });
前臺用的bootstrap 框架 ,所以input 用的是它自帶的樣式。如果你用的是普通的input 標籤,那你加一個onchange事件,然後把上邊else 中的記憶體貼上適當修改即可。如果沒看懂,那就只好你上網查一下咯,上面講的也挺詳細。剪裁圖片首先跳轉我自己的action ,由action再呼叫 下面的ImageUtil類。以下是我根據專案的業務需求而制定的符合自己標準的解決辦法,如果沒看懂,就再討論吧。之前就只貼出了ImageUtil類的程式碼,發現好像不是能看的懂,就把大多數給粘了出來
/*** * 剪裁圖片 * @throws IOException */ public void cutPhoto() throws IOException{ String actionPath = getRequest().getSession().getServletContext().getRealPath(""); String srcImageFile = actionPath + "/" +formInfo.getPhoto(); int max_w= 400; //圖片佈局區域最大寬度值 int max_h = 300; //圖片佈局區域最大高度值
File file = new File(srcImageFile);
BufferedImage bufferImage = ImageIO.read(file); //本地原始圖片地址
int src_w = bufferImage.getWidth(); //取原圖寬度
int src_h = bufferImage.getHeight(); //取原圖高度
int w= 0; //圖片展示區域寬度
int h = 0; //圖片展示區域高度
//裁剪區間展示區域的的長寬比
float cutScale = (float)max_w/(float)max_h;
//原圖的長寬比
float srcScale = (float)src_w/(float)src_h;
//上傳圖片(即原圖片)的寬高 小於 展示區域的圖片寬高的最大設定
if(max_w > src_w && max_h > src_h){
w = src_w;
h = src_h;
}else{
if(max_w > max_h){
//原圖的K寬高比 大於等於 裁剪區間展示區域的的長寬高比
if(srcScale >= cutScale){
w = max_w;
h = (max_w*src_h)/src_w;
}else{
w = (max_h*src_w)/src_h;
h = max_h;
} //else
} //if
else{
//原圖的K寬高比 大於等於 裁剪區間展示區域的的長寬高比
if(srcScale >= cutScale){
w = max_w;
h = (max_w*src_h)/src_w;
}else{
w = (max_h*src_w)/src_h;
h = max_h;
} //else
} //else
} //else
//剪裁區域相對於原始圖的X軸座標
int rect_x = (formInfo.getX1()*src_w)/w;
//剪裁區域相對於原始圖的y軸座標
int rect_y = (formInfo.getY1()*src_h)/h;
//剪裁後圖片的寬度
int width = (formInfo.getW()*src_w)/w;
//剪裁後圖片的高度
int height = (formInfo.getH()*src_h)/h;
Rectangle rect = new Rectangle(rect_x, rect_y, width, height);
FileOutputStream fs = new FileOutputStream(srcImageFile);
//獲取圖片格式
String formatName = srcImageFile.substring(srcImageFile.lastIndexOf('.') + 1);
//設定新輸出圖片的路徑和名稱
ImageIO.write(bufferImage, formatName, fs);
//關閉輸入流
fs.close();
//按照縮放的比例剪裁圖片
ImageUtil.cutImages(srcImageFile, rect, width, height);
}
2. 剪裁功能 最重要的是程式碼的實現 接下來 把我實現這個功能所用的程式碼(對於實現剪裁的方法 ,我抽取了出來,作為一個工具類) 粘貼出來 分享給需要的人
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
public class ImageUtil {
/**
* 剪裁圖片
* @param srcImageFile 要剪裁圖片的路徑
* @param rect 剪裁範圍
* @param width 剪裁寬度
* @param height 剪裁高度
* @throws IOException
*/
public static void cutImages(String srcImageFile,Rectangle rect,int width,int height) throws IOException{
//獲取圖片格式
String formatName = srcImageFile.substring(srcImageFile.lastIndexOf('.') + 1);
Iterator iterator = ImageIO.getImageReadersByFormatName(formatName);
ImageReader reader = (ImageReader) iterator.next();
InputStream in = new FileInputStream(srcImageFile);
ImageInputStream iis = ImageIO.createImageInputStream(in);
reader.setInput(iis, true);
ImageReadParam param = reader.getDefaultReadParam();
param.setSourceRegion(rect);
BufferedImage bi = reader.read(0, param);
ImageIO.write(bi, formatName, new File(srcImageFile));
File file = new File(srcImageFile);
BufferedImage bufferImage = ImageIO.read(file);
//將上傳的圖片等比例縮放
bufferImage = resize(bufferImage,width,height,srcImageFile);
FileOutputStream fs = new FileOutputStream(srcImageFile);
ImageIO.write(bufferImage, formatName, fs); // 設定新輸出圖片的路徑和名稱
fs.close(); //關閉輸入流
}
/**
* 圖片等比縮放
* @param source 要剪裁的圖片
* @param targetW 剪裁寬度
* @param targetH 剪裁高度
* @param name 剪裁好的圖片路徑名
* @return
* @throws IOException
*/
public static BufferedImage resize(BufferedImage source, int targetW, int targetH, String name) throws IOException {
int type = source.getType();
BufferedImage target = null;
double sx = (double) targetW / source.getWidth(); // 寬度
double sy = (double) targetH / source.getHeight(); // 長度
// 這裡想實現在targetW,targetH範圍內實現等比縮放
if (sx == sy) { // 長度和寬度相同
sy = sx;
targetH = (int) (sy * source.getHeight());
} else { // 不相等
targetW = (int) (sx * source.getWidth());
targetH = (int) (sy * source.getHeight());
}
if (type == BufferedImage.TYPE_CUSTOM) {
ColorModel cm = source.getColorModel();
WritableRaster raster = cm.createCompatibleWritableRaster(targetW, targetH);
boolean alphaPremultiplied = cm.isAlphaPremultiplied();
target = new BufferedImage(cm, raster, alphaPremultiplied, null);
} else {
// 固定寬高,寬高一定要比原圖片大
target = new BufferedImage(targetW, targetH, type);
}
Graphics2D g = target.createGraphics();
// 寫入背景
g.drawImage(ImageIO.read(new File(name)), 0, 0, null);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.drawRenderedImage(source, AffineTransform.getScaleInstance(sx, sy));
g.dispose();
return target;
}
}
該功能所需css 、js 下載地址:http://download.csdn.net/detail/who_is_xiaoming/9454237 (不需要下載分即可下載哦 ~~~)
如果 該功能確實遇到不理解的 可以在文章下方回覆~~~