java 使用Jcrop 实现图像剪裁功能

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   (不需要下载分即可下载哦 ~~~)

如果 该功能确实遇到不理解的  可以在文章下方回复~~~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值