使用imgareaselect 辅助后台进行图片裁剪

由于项目其中用到图片裁剪,本来能够不用到后台进行裁剪的,可是要兼容万恶的IE浏览器,所以不得不使用后台进行裁剪。

这次使用到imgareaselect?插件获取须要裁剪区域的坐标。再由后台进行裁剪操作。

先上个效果图再说

可是这里有一个坑就是上传的图片过大,可能会造成裁剪的区域跟插件中显示的不一样,所以得如今后台对云图片进行压缩在裁剪

/**
	 * 等比例压缩算法:
	 * 算法思想:依据压缩基数和压缩比来压缩原图,生产一张图片效果最接近原图的缩略图
	 * @param srcURL 原图地址
	 * @param deskURL 缩略图地址
	 * @param comBase 压缩基数
	 * @param scale 压缩限制(宽/高)比例  一般用1:
	 * 当scale>=1,缩略图height=comBase,width按原图宽高比例;若scale<1,缩略图width=comBase,height按原图宽高比例
	 * @throws Exception

	 */
	public static void saveMinPhoto(String srcURL, String deskURL, double comBase,
			double scale) throws Exception {
		File srcFile = new java.io.File(srcURL);
		String ext = srcURL.substring(srcURL.lastIndexOf(".") + 1);
		Image src = ImageIO.read(srcFile);
		int srcHeight = src.getHeight(null);
		int srcWidth = src.getWidth(null);
		int deskHeight = 0;// 缩略图高
		int deskWidth = 0;// 缩略图宽
		double srcScale = (double) srcHeight / srcWidth;
		/**缩略图宽高算法*/
		if ((double) srcHeight > comBase || (double) srcWidth > comBase) {
			if (srcScale >= scale || 1 / srcScale > scale) {
				if (srcScale >= scale) {
					deskHeight = (int) comBase;
					deskWidth = srcWidth * deskHeight / srcHeight;
				} else {
					deskWidth = (int) comBase;
					deskHeight = srcHeight * deskWidth / srcWidth;
				}
			} else {
				if ((double) srcHeight > comBase) {
					deskHeight = (int) comBase;
					deskWidth = srcWidth * deskHeight / srcHeight;
				} else {
					deskWidth = (int) comBase;
					deskHeight = srcHeight * deskWidth / srcWidth;
				}
			}
		} else {
			deskHeight = srcHeight;
			deskWidth = srcWidth;
		}
		BufferedImage tag = new BufferedImage(deskWidth, deskHeight, BufferedImage.TYPE_3BYTE_BGR);
		tag.getGraphics().drawImage(src, 0, 0, deskWidth, deskHeight, null); //绘制缩小后的图
		FileOutputStream deskImage = new FileOutputStream(deskURL); //输出到文件流
		ImageIO.write(tag, ext, new File(deskURL));
		deskImage.close();
	}

这就是压缩之后在进行裁剪了。好了上完整代码先

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>上传头像</title>
<link rel="stylesheet" href="../../statics/css/ewt/style_1.css" type="text/css">
<link rel="stylesheet" href="../../statics/css/ewt/style_shangchuangtouxiang.css">
<link rel="stylesheet" type="text/css" href="../../statics/css/ewt/imgareaselect-default.css">
<link rel="stylesheet" href="../../statics/css/ewt/style.css" type="text/css" />
<link rel="stylesheet" href="../../statics/scripts/layer/skin/default/layer.css">
<script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
<script src="../../statics/scripts/include.js"></script>
<script src="../../statics/scripts/template.js"></script>
<script src="../../statics/scripts/layer/layer.js"></script>
<script src="../../statics/scripts/cropbox.js"></script>
<script src="../../statics/scripts/jquery.imgareaselect.pack.js"></script>
<script src="../../statics/scripts/ajaxfileupload.js"></script>
<script src="../../ewt/user/scripts/shangchuangtouxiang.js"></script>
<script src="../../ewt/common/config.js"></script>

</head>

<body>
<include src="../common/user_head.html"></include>
<div class="bggg">
<div class="box">
 <div class="bos">
   <include src="../common/user_menu.html"></include>
  <div class="bos_r">
  <div class="biaoti">
        <h3>上传头像</h3>
      </div>
  <div style=" width:915px; height: 400; display: block; overflow: hidden; margin: 30px auto; ">
       <div style=" width:430px;  margin:0 auto;">
       <div class="frame" style="margin: 0 0.3em; width: 300px; height: 300px; float: left;">
      <img id="photo" src="" style="width: 300px; height: 300px;"/>
    </div>

    <div id="preview" style="width: 100px; height: 100px; overflow: hidden; float: left;">
        <img src="" style="width: 100px; height: 100px;" id="smallImage"/>
    </div>
    </div>
    </div>
    <div  style=" width:425px;  margin:30px auto;">
    <div class="input_XZ1">
    <div class="input_XZ">选择图片</div>
    <input id="uplodimage"  class="input_style"   name="uplodimage" type="file" onchange="uplodImage(this)">
    </div>
     <input id="imgUrl" type="hidden">
    <input type="button" value="上传" class="input_SC" onclick="upold();">
    </div>
	<input type="hidden" id="x1" value="" />
	<input type="hidden" id="y1" value="" />
	<input type="hidden" id="x2" value="" />
	<input type="hidden" id="y2" value="" />
	<input type="hidden" id="w" value="" />
	<input type="hidden" id="h" value="" />

</div>
</div>
</div>

</div> 

<include src="../common/user_footer.html"></include>
</body>
</html>

js 代码

function preview(img, selection) {
    if (!selection.width || !selection.height)
        return;

    var scaleX = 100 / selection.width;
    var scaleY = 100 / selection.height;

    $(‘#preview img‘).css({
        width: Math.round(scaleX * 300),
        height: Math.round(scaleY * 300),
        marginLeft: -Math.round(scaleX * selection.x1),
        marginTop: -Math.round(scaleY * selection.y1)
    });

    $(‘#x1‘).val(selection.x1);
    $(‘#y1‘).val(selection.y1);
    $(‘#x2‘).val(selection.x2);
    $(‘#y2‘).val(selection.y2);
    $(‘#w‘).val(selection.width);
    $(‘#h‘).val(selection.height);
}

$(function () {

});

//上传原始图片
function uplodImage(target) {
	if(checkImage(target)){
		var url = httpUtils.rootPath+‘/component/upload.do‘;
		$.ajaxFileUpload({
		    url: url, //用于文件上传的服务器端请求地址
		    secureuri: false, //是否须要安全协议,一般设置为false
		    fileElementId: ‘uplodimage‘, //文件上传域的ID
		    dataType: ‘json‘, //返回值类型 一般设置为json
		    success: function (data)  //服务器成功响应处理函数
		    {
		        var filePath =  data.filePath;
		        $(‘#photo‘).attr(‘src‘,httpUtils.rootPath+‘/component/upload.do?action=download&filepath=‘+filePath);
		        $(‘#smallImage‘).attr(‘src‘,httpUtils.rootPath+‘/component/upload.do?

action=download&filepath=‘+filePath);
		        $(‘#imgUrl‘).val(filePath);
		         $(‘#photo‘).imgAreaSelect({
    	aspectRatio: ‘1:1‘,
    	x1: 50, y1: 50, x2: 241, y2: 241,
   	 	handles: true,
    	fadeSpeed: 200,
    	onSelectChange: preview
    });
    $(‘#x1‘).val("50");
   	$(‘#y1‘).val("50");
    $(‘#x2‘).val("241");
    $(‘#y2‘).val("241");
    $(‘#w‘).val("191");
    $(‘#h‘).val("191");
		     }
		   });
	}

}

//上传裁剪后的图片
function upold() {

	if($(‘#imgUrl‘).val()==‘‘){
		layer.alert("请先选择图片在上传");
		return false;
	}

	$.ajax({
             type: "post",
             url:httpUtils.rootPath+‘/user/setHeadPicture‘,
             beforeSend: function(request) {
        		request.setRequestHeader("jmtcp", header);
        	},
             async:false,
             data: {
             	x:$(‘#x1‘).val(),
             	y:$(‘#y1‘).val(),
             	width: $(‘#w‘).val(),
             	imgUrl : $(‘#imgUrl‘).val(),
             	heigth: $(‘#h‘).val()
             },
             dataType: "json",
             success: function(data){
             			if(data.code==1){

             				layer.alert(data.message,function(){
             					window.location.href = ‘../user/grzy.html‘;
             				});
             			}else{
             				layer.alert(data.message);
             			}
                     }
         });
}

function checkImage(target) {
	var isIE = /msie/i.test(navigator.userAgent) && !window.opera;
	 var fileSize = 0;
	 var filepath = target.value;
	// 为了避免转义反斜杠出问题。这里将对其进行转换
		var re = /(\+)/g;
		var filename = filepath.replace(re, "#");
		// 对路径字符串进行剪切截取
		var one = filename.split("#");
		// 获取数组中最后一个,即文件名称
		var two = one[one.length - 1];
		// 再对文件名称进行截取,以取得后缀名
		var three = two.split(".");
		// 获取截取的最后一个字符串,即为后缀名
		var last = three[three.length - 1];
		// 加入须要推断的后缀名类型
		var tp = "jpg,gif,bmp,JPG,GIF,BMP,png";
		// 返回符合条件的后缀名在字符串中的位置
		var rs = tp.indexOf(last);
		// 假设返回的结果大于或等于0。说明包括同意上传的文件类型
		if(rs < 0){
			layer.alert(‘您选择的上传文件不是有效的图片文件‘);
			return false;
		}
//    if (isIE && !target.files) {    // IE浏览器
//        var filePath = target.value; // 获得上传文件的绝对路径
//        var fileSystem = new ActiveXObject("Scripting.FileSystemObject");
//        // GetFile(path) 方法从磁盘获取一个文件并返回。
//        var file = fileSystem.GetFile(filePath);
//        fileSize = file.Size;    // 文件大小。单位:b
//    }
//    else {    // 非IE浏览器
//        fileSize = target.files[0].size;
//    }
		 var img1 = document.getElementById(‘photo‘);
    	//img1.dynsrc=target.value;
        //img1.fileSize:IE , fileObj.files[0].fileSize:chrome, fileObj.files[0].size:FF
    	var fileSize = img1.fileSize || target.files[0].fileSize || target.files[0].size;
    var size = fileSize / 1024 / 1024;
    if (size > 5) {
        layer.alert("图片不能大于5M");
        return false;
    }
    return true;
}

后台代码

public class CutImageUtils {
	public static SecureRandom rnd = new SecureRandom();

	public static String cutImage(int x, int y, int width, int height,String srcPath) throws Exception{
		String root = ApplicationContext.getProperty("upload_folder");
		String imagePath = root+srcPath;
		 FileInputStream is = null;
	     ImageInputStream iis = null;
	     String uploadFolder = null ;
		String filepath = null  ;
		String serverName = null  ;
		uploadFolder = ApplicationContext.getProperties().getProperty("upload_folder").toString() ;
		filepath = generateServerFolder() ;
		serverName = generateServerName(srcPath) ;
        File file = new File(uploadFolder + filepath);
        if (!file.exists()) {
			file.mkdirs();
		} 

         try {
        	// 读取图片文件
        	saveMinPhoto(imagePath, imagePath, 300, 0.9d);
        	 //resetsize(imagePath, imagePath);
			is = new FileInputStream(imagePath);
			String ext = srcPath.substring(srcPath.lastIndexOf(".") + 1);
			 Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName(ext);
			 ImageReader reader = it.next();
			// 获取图片流
	         iis = ImageIO.createImageInputStream(is);
	         reader.setInput(iis, true);
	         ImageReadParam param = reader.getDefaultReadParam();
	         /**
	             *
	             * 图片裁剪区域。Rectangle 指定了坐标空间中的一个区域。通过 Rectangle 对象
	             *
	             * 的左上顶点的坐标(x,y)、宽度和高度能够定义这个区域。

*/
	          Rectangle rect = new Rectangle(x, y, width, height);  

	            // 提供一个 BufferedImage。将其用作解码像素数据的目标。
	          param.setSourceRegion(rect);
	          BufferedImage bi = reader.read(0, param);
	          // 保存新图片
	         ImageIO.write(bi, ext, new File(uploadFolder + filepath + serverName));
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			if (is != null)
                is.close();
            if (iis != null)
                iis.close();
			e.printStackTrace();
		}
         return  filepath + serverName ;
	}

	   /**
     *
     * @param config
     * @param file
     * @param request
     * @return
     */
    public static String generateServerName(String clientPath) {
        //按当前时间的分钟毫秒+3位随机数
        Calendar c = Calendar.getInstance();
        String min  = get(c,Calendar.MINUTE);
        String sec  = get(c,Calendar.SECOND);
        String mis  = get(c,Calendar.MILLISECOND);
        String rnd  = random();
        String ext  = getFileExt(getClientName(clientPath));

        return min + sec + mis + rnd + ext ;
    }

    /** 客户端文件名称 */
    public static String getClientName(String clientPath) {
        if(null != clientPath){
            int index1 = clientPath.lastIndexOf("/");
            int index2 = clientPath.lastIndexOf("\\");
            if(index2 > index1){
                index1 = index2;
            }
            return clientPath.substring(index1+1,clientPath.length());
        }
        return null;
    }

    public static String getFileExt(String fileName){
        if(null != fileName){
            int dot = fileName.lastIndexOf(".");
            if(dot >= 0){
                return fileName.substring(dot);
            }
        }
        return "";
    }

    public static String random(){
        String value = String.valueOf(rnd.nextInt(1000));
        if(value.length() < 3){
            for(int i=value.length();i<3;i++){
                value = "0" + value;
            }
        }
        return value;
    }

    public static String generateServerFolder() {
        //按当前年月日和小时生成文件路径
        Calendar c  = Calendar.getInstance();
        String year = get(c,Calendar.YEAR);
        String mon  = get(c,Calendar.MONTH);
        String day  = get(c,Calendar.DAY_OF_MONTH);
        String hour = get(c,Calendar.HOUR_OF_DAY);

        return year + "/" + mon + "/" + day + "/" + hour + "/";
    }

    public static String get(Calendar c,int field){
        int v = c.get(field);
        if(field == Calendar.MONTH){
            v += 1;
        }
        String value = String.valueOf(v);
        if(value.length() == 1){
            value = "0" + value;
        }
        return value;
    }

    /**
     * 缩小图片到固定长高
     * @param srcImagePath 读取图片路径
     * @param toImagePath 写入图片路径
     * @param width 缩小后图片宽度
     * @param height 缩小后图片长度
     * @throws IOException
     */
	public static void reduceImageByWidthHeight(String srcImagePath, String toImagePath, int width, int height) throws IOException{
        FileOutputStream out = null;
        try{
            //读入文件
            File file = new File(srcImagePath);
            String ext = srcImagePath.substring(srcImagePath.lastIndexOf(".") + 1);
            // 构造Image对象
            BufferedImage src = javax.imageio.ImageIO.read(file);
            // 缩小边长
            BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            // 绘制缩小后的图片
            tag.getGraphics().drawImage(src, 0, 0, width, height, null);
            out = new FileOutputStream(toImagePath);
            ImageIO.write(tag, ext, new File(toImagePath));
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            if(out != null){
                out.close();
            }
            out = null;
            System.gc();
        }
    }

	/**
	 * 等比例压缩算法:
	 * 算法思想:依据压缩基数和压缩比来压缩原图。生产一张图片效果最接近原图的缩略图
	 * @param srcURL 原图地址
	 * @param deskURL 缩略图地址
	 * @param comBase 压缩基数
	 * @param scale 压缩限制(宽/高)比例  一般用1:
	 * 当scale>=1,缩略图height=comBase,width按原图宽高比例;若scale<1,缩略图width=comBase,height按原图宽高比例
	 * @throws Exception

	 */
	public static void saveMinPhoto(String srcURL, String deskURL, double comBase,
			double scale) throws Exception {
		File srcFile = new java.io.File(srcURL);
		String ext = srcURL.substring(srcURL.lastIndexOf(".") + 1);
		Image src = ImageIO.read(srcFile);
		int srcHeight = src.getHeight(null);
		int srcWidth = src.getWidth(null);
		int deskHeight = 0;// 缩略图高
		int deskWidth = 0;// 缩略图宽
		double srcScale = (double) srcHeight / srcWidth;
		/**缩略图宽高算法*/
		if ((double) srcHeight > comBase || (double) srcWidth > comBase) {
			if (srcScale >= scale || 1 / srcScale > scale) {
				if (srcScale >= scale) {
					deskHeight = (int) comBase;
					deskWidth = srcWidth * deskHeight / srcHeight;
				} else {
					deskWidth = (int) comBase;
					deskHeight = srcHeight * deskWidth / srcWidth;
				}
			} else {
				if ((double) srcHeight > comBase) {
					deskHeight = (int) comBase;
					deskWidth = srcWidth * deskHeight / srcHeight;
				} else {
					deskWidth = (int) comBase;
					deskHeight = srcHeight * deskWidth / srcWidth;
				}
			}
		} else {
			deskHeight = srcHeight;
			deskWidth = srcWidth;
		}
		BufferedImage tag = new BufferedImage(deskWidth, deskHeight, BufferedImage.TYPE_3BYTE_BGR);
		tag.getGraphics().drawImage(src, 0, 0, deskWidth, deskHeight, null); //绘制缩小后的图
		FileOutputStream deskImage = new FileOutputStream(deskURL); //输出到文件流
		ImageIO.write(tag, ext, new File(deskURL));
		deskImage.close();
	}

    public static void main(String[] args) {
    	try {
			String src = CutImageUtils.cutImage(11, 12, 100, 100, "2017/01/04/17/6348162d-5b50-4e7d-b414-93140498f8de.jpg");
			System.out.println(src);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

原文地址:https://www.cnblogs.com/llguanli/p/8452788.html

时间: 2024-10-09 21:43:27

使用imgareaselect 辅助后台进行图片裁剪的相关文章

利用jquery的imgAreaSelect插件实现图片裁剪示例

利用jquery的imgAreaSelect插件实现图片裁剪示例 将用户上传的图片进行裁剪再保存是现在web2.0应用中常常处理的工作,现在借助jquery的imgareaselect插件再配合PHP的GD库就可以轻松的实现这个在以前来说非常棘手的功能.我们来看看它的实现步骤: 1.包含进CSS文件(imgareaselect-default.css)和 jquery.imgareaselect.js文件 2.html代码(要裁剪的图片元素) <img id="selectbanner&q

前台Jcrop配合后台Graphics实现图片裁剪并上传

Jcrop:一个功能强大的图片裁剪插件 版本:Jcrop v0.9.12 VS版本:vs2015 下载地址:http://code.ciaoca.com/jquery/jcrop/version/Jcrop-0.9.12.zip 本文主要讲的是,在前台通过file选择图片,然后用Jcrop裁剪好图片后,把偏移量等参数传值到后台,在后台通过Graphics进行图片的截取并上传到服务器,显示一下重点代码 HTML 部分<div class="example"> <img

JavaScript图片裁剪

1.jquery 图片裁剪库选择 Jcrop:http://deepliquid.com/content/Jcrop.html imgareaselect:http://odyniec.net/projects/imgareaselect/ CropZoom:https://github.com/cropzoom/cropzoom 可供选择的jQuery插件非常多,这里选择 imgareaselect 进行详细演示 2.综合演示效果 2.1 左侧区域是 div + img 标签,用来展示原图,具

cropper.js图片裁剪

最近做电子名片的项目,可是个人照片展示上出现了 用户上传的图片尺寸严重失调,所以要求进行图片裁剪,再此我对图片裁剪进行调研 还不太成熟 以后再改 这个实现的原理是 前台获取到 坐标 图片的尺寸 原图文件 传给后台进行裁剪 这个是我在网上找的一个插件 cropper功能很强大 这里是官方文档 首先使用cropper必须引入对应得css和js,还有jquery <script src="jquery.js"></script> <link href="

移动端图片裁剪解决方案

1.需求 移动端头像裁剪功能 2.解决方案 使用jq和jcrop插件完成 3.解决思路 先把可移动的层的左上角左边和长宽传到后端,后端获得这些数据之后用gd库的函数去裁剪服务端的图片. 默认要裁剪的图片已经上传到后台,图片上传的解决方案这下面链接 http://www.cnblogs.com/norm/p/6188318.html 4.具体代码 a.引入类库 <link rel="stylesheet" href="css/jquery.Jcrop.css"&

使用canvas进行图片裁剪简单功能

1.html部分 使用一个input[type="file"]进行图片上传: canvas进行图片的裁剪展示 <div> <input type="file" id="imgFile"> </div> <div id="demoBox" style="width: 300px;height: 300px;position: absolute;left: 300px;top:

使用JCrop进行图片裁剪,裁剪js说明,裁剪预览,裁剪上传,裁剪设计的图片处理的工具类和代码

?? 1.要想制作图片裁剪功能,可以使用网上的裁剪工具JCrop,网址是:https://github.com/tapmodo/Jcrop/ 案例效果如下: 2.引入JCrop的js代码,具体要引入那些js可以参考JCrop案例: 3.编写的html代码如下: <div id="light" class="white_content"> <div class="vatitlee"> 封面截取 <div class=&

5款好用的开源JS图片裁剪插件(3个jQuery插件,2个AngularJS插件)

tapmodo / Jcrop Jcrop是人气最高的图片裁剪jQuery插件,stars数量2k+,功能非常丰富,文档齐全,首选.Github.com官网也使用了这个插件.有一个小细节是,边框线的蚂蚁线是动画的,真的很用心. Jcrop项目地址 | demo1 | demo2 | demo3 | demo4 fengyuanchen / cropper Cropper也是一款图片裁剪jQuery插件,stars数量1k+,是杭州的前端工程师Fengyuan Chen所写的,功能也相当丰富,裁剪

浮士德html5图片裁剪器2016开源版

前言 最近刚刚好整理浮士德头像裁剪的flash版本,为了某些低级浏览器的兼容着想,既然已经做好了flash版本了,那么,现代浏览器的html5版本和ipad版,移动版也要做一些处理和打包. 兼容性 兼容ie10及以上,google浏览器,Firefox浏览器,safari浏览器,兼容ipad,苹果,安卓等机型. 历史文档 话说图片裁剪这个是很常见的需求,但是做到精细化和兼容处理也是相当费工夫的,本人光是博客相关文件都有7.8篇了,解决的大大小小bug不计其数,本插件不但解决了下面的各种bug,而