springboot+Jcrop实现图片裁剪(模仿邮箱注册上传头像)

1、pom配置

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>


<groupId>com.xfs.common.services</groupId>

<artifactId>base-services</artifactId>

<version>0.0.1-SNAPSHOT</version>

<packaging>jar</packaging>


<name>base-services</name>

<description>Demo project for Spring Boot</description>


<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.0.1.RELEASE</version>

<relativePath/> <!-- lookup parent from repository -->

</parent>


<properties>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

<java.version>1.8</java.version>

</properties>


<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>


<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

</dependency>


<dependency>

<groupId>commons-fileupload</groupId>

<artifactId>commons-fileupload</artifactId>

<version>1.2.2</version>

</dependency>


<dependency>

<groupId>commons-io</groupId>

<artifactId>commons-io</artifactId>

<version>2.4</version>

</dependency>


<dependency>

<groupId>com.aliyun.oss</groupId>

<artifactId>aliyun-sdk-oss</artifactId>

<version>2.8.1</version>

</dependency>


<!-- jersey -->

<dependency>

<groupId>com.sun.jersey</groupId>

<artifactId>jersey-server</artifactId>

<version>1.10</version>

</dependency>

<dependency>

<groupId>com.sun.jersey</groupId>

<artifactId>jersey-client</artifactId>

<version>1.10</version>

</dependency>

<dependency>

<groupId>com.sun.jersey</groupId>

<artifactId>jersey-core</artifactId>

<version>1.10</version>

</dependency>


<dependency>

<groupId>log4j</groupId>

<artifactId>log4j</artifactId>

<version>1.2.17</version>

</dependency>

</dependencies>


<build>

<plugins>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

</plugin>

</plugins>

</build>

</project>

2、引入相关js、css
<link rel="stylesheet" href="css/jquery.Jcrop.css" type="text/css">
<script src="js/jquery.min.js"></script>
<script src="js/jquery.Jcrop.js"></script>
<script src="js/jquery-form.js"></script>

3、html页面
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" type="text/css" href="css/bullet.css">
<link rel="stylesheet" type="text/css" href="../../static/h-ui/css/H-ui.min.css"/>
<title>企业logo弹窗</title>
<link rel="stylesheet" href="css/jquery.Jcrop.css" type="text/css">
<script src="js/jquery.min.js"></script>
<script src="js/jquery.Jcrop.js"></script>
<script src="js/jquery-form.js"></script>
<script type="text/javascript">
/* jcrop对象,全局变量方便操作 */
var api = null;
/* 原图宽度 */
var boundx;
/* 原图高度 */
var boundy;

/* 选择图片事件 */
function readURL(URL){
var reader = new FileReader();
reader.readAsDataURL(URL.files[0]);
reader.onload = function(e){
$("#faceId").removeAttr("src");
$("#lookId").removeAttr("src");
$("#faceId").attr("src",e.target.result);
$("#lookId").attr("src",e.target.result);
$("#faceId").Jcrop({
onChange: showPreview,
onSelect: showPreview,
aspectRatio: 1,
boxWidth:600
},function(){
// Use the API to get the real image size
//使用API来获得真实的图像大小
var bounds = this.getBounds();
boundx = bounds[0];
boundy = bounds[1];
// Store the API in the jcrop_api variable
//jcrop_api变量中存储API
api = this;

$("#boundx").val(boundx);
$("#boundy").val(boundy);

});
};
/* 移除jcrop */
if (api != undefined) {
api.destroy();
}

//简单的事件处理程序,响应自onChange,onSelect事件,按照上面的Jcrop调用
function showPreview(coords){
/* 设置剪切参数 */
$("#x").val(coords.x);
$("#y").val(coords.y);
$("#w").val(coords.w);
$("#h").val(coords.h);
if(parseInt(coords.w) > 0){
//计算预览区域图片缩放的比例,通过计算显示区域的宽度(与高度)与剪裁的宽度(与高度)之比得到
var rx = $("#preview_box").width() / coords.w;
var ry = $("#preview_box").height() / coords.h;
$("#lookId").css({
width:Math.round(rx * $("#faceId").width()) + "px", //预览图片宽度为计算比例值与原图片宽度的乘积
height:Math.round(rx * $("#faceId").height()) + "px", //预览图片高度为计算比例值与原图片高度的乘积
marginLeft:"-" + Math.round(rx * coords.x) + "px",
marginTop:"-" + Math.round(ry * coords.y) + "px"
});
}
}

}



$(function () {
$('#save').click(function(){

alert(1)
$('#uploadImgForm').ajaxSubmit({
url:"http://192.168.65.115:8110/basicservice/upload",
type:"post", //提交方式
success:function (data) {
alert(data);
}
})
})
})

</script>
</head>

<body>
<div tabindex="-1" role="dialog" aria-labelledby="myModalLabel" >
<div class="modal-dialog" style="width:880px;">
<div class="modal-content radius">
<div class="modal-header">
<h3 class="modal-title">企业logo编辑</h3>
<a class="close" data-dismiss="modal" aria-hidden="true" href="javascript:;">×</a>
</div>
<div class="modal-body modal-center">
<div class="main">
<div class="mainLeft" align="center">
<span>要求:请使用真实企业图片,图片格式支持JPG,JPEG,GIF,PNG,支持5M 以内的图片</span>
<div class="background" >
<form name="form" id="uploadImgForm" class="form-horizontal" method="post" enctype="multipart/form-data">
<div class="modal-body text-center">
<div class="zxx_main_con">
<div class="zxx_test_list">
<a href="javascript:;" class="file"><input class="photo-file" type="file" name="file" id="fcupload" οnchange="readURL(this);" />选择图片</a>
<input type="hidden" name="isNeetCut" value="10">
<img id = "faceId" src="${pageContext.request.contextPath}/static/img/1.jpg" class="jcrop-preview">
<!-- 图片长宽高隐藏域 -->
<input type="hidden" id="x" name="x" />
<input type="hidden" id="y" name="y" />
<input type="hidden" id="w" name="w" />
<input type="hidden" id="h" name="h" />
<input type="hidden" id="boundx" name="boundx" >
<input type="hidden" id="boundy" name="boundy" >
</div>
</div>
</div>

</form>
</div>
</div>
<div class="mainRight" align="center">
<span class="effect">效果预览</span><br>
<span class="px">100*100像素</span>
<div class="background" >
<div style="width: 200px;height: 200px;overflow: hidden;" id = "preview_box" style="border: black">
<img id = "lookId" src="${pageContext.request.contextPath}/static/img/1.jpg" class="jcrop-preview" alt="预览" >
</div>
<input type="button" id="save" value="确定上传" class="selectPic">
</div>
</div>
<div style="clear:both"></div>
</div>
</div>

</div>
</div>
</div>
</body>
</html>
4、图片裁剪工具类 CutImgeUtil

package com.xfs.common.services.baseservices.util;


import com.aliyun.oss.OSSClient;

import com.sun.jersey.api.client.Client;

import com.sun.jersey.api.client.WebResource;

import org.apache.log4j.Logger;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.context.annotation.Configuration;


import javax.imageio.ImageIO;

import java.awt.*;

import java.awt.image.BufferedImage;

import java.awt.image.CropImageFilter;

import java.awt.image.FilteredImageSource;

import java.awt.image.ImageFilter;

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;



/**

* 裁剪图片

*

* @author :ZHANGPENGFEI

* @create 2018-06-07 17:05

**/

public class CutImgeUtil {


private static Logger logger = Logger.getLogger(CutImgeUtil.class);


/**

* 图片剪切工具类

* @param input 图片输入流

* @param x 截取时的x坐标

* @param y 截取时的y坐标

* @param desWidth 截取的宽度

* @param desHeight 截取的高度

* @param srcWidth 页面图片的宽度

* @param srcHeight 页面图片的高度

* @param newFileName 图片的新名称

* @param suffix 后缀

* @return

*/

public List<Map<String,String>> cutImge(InputStream input, int x, int y, int desWidth, int desHeight, int srcWidth,

int srcHeight, String newFileName, String suffix,Integer flag,Integer catalog,String IMG_SECURITY){


List<Map<String,String>> resultList = new ArrayList<>();


try

{

//图片类

Image imge ;

ImageFilter cropFilter;


//读取图片

BufferedImage bi = ImageIO.read(input);


//当剪裁大小小于原始图片大小才执行

if(srcWidth >= desWidth && srcHeight >= desHeight)

{

//获取原始图

Image image = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT);

//获取新图

cropFilter = new CropImageFilter(x, y, desWidth, desHeight);

imge = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(image.getSource(), cropFilter));

BufferedImage tag = new BufferedImage(desWidth, desHeight, BufferedImage.TYPE_INT_RGB);

Graphics g = tag.getGraphics();

g.drawImage(imge, 0, 0, null);

g.dispose();


ByteArrayOutputStream out = new ByteArrayOutputStream();

try {


//定义上传目录

String catalogPath = null;

if (null != catalog){

if (11 == catalog){

//上传至product

catalogPath = "product/";

}else {

//上传至common

catalogPath = "common/";

}

}else {

//上传至common

catalogPath = "common/";

}


if (1 == flag){

ImageIO.write(tag, suffix, out);

byte[] bytes = out.toByteArray();

//创建jesy服务器

Client client = Client.create();

String fullPath = "http://192.168.0.106:8200/img/" + catalogPath +newFileName+"_cut."+suffix;

String reletivePath = catalogPath+newFileName+suffix;

//把文件关联到远程服务器

WebResource wr = client.resource(fullPath);

//上传

wr.put(String.class, bytes);

Map<String , String> map = new HashMap<String, String>();

//7.保存图片全路径

map.put("fullPath", fullPath+IMG_SECURITY);

//8.保存图片相对路径

map.put("reletivePath", reletivePath+IMG_SECURITY);

resultList.add(map);

return resultList;

}else {

//5.上传图片服务器

ImageIO.write(tag, suffix, out);

InputStream inputStream = new ByteArrayInputStream(out.toByteArray());

OSSClient ossClient = OSSUtils.getOSSClient();

String imgUrl = OSSUtils.uploadObjectOSS(ossClient, inputStream, catalogPath, newFileName+suffix);

String reletivePath = catalogPath+newFileName+suffix;

//6.上传

ossClient.shutdown();

Map<String , String> map = new HashMap<String, String>();

//7.保存图片全路径

map.put("fullPath", imgUrl+IMG_SECURITY);

//8.保存图片相对路径

map.put("reletivePath", reletivePath+IMG_SECURITY);

resultList.add(map);

return resultList;

}


} catch (IOException e) {

e.printStackTrace();

Map<String , String> map = new HashMap<String, String>();

map.put("errorInfo","剪切失败...");

map.put("errorCode","1");

resultList.add(map);

}

}


} catch (Exception e)

{


e.printStackTrace();

Map<String , String> map = new HashMap<String, String>();

map.put("errorInfo","剪切失败...");

map.put("errorCode","1");

resultList.add(map);

}


return resultList;

}

}

5、校验图片类型 FileUploadCheck

/**

* 校验文件类型

*

* @author :ZHANGPENGFEI

* @create 2018-06-07 17:05

**/

public class FileUploadCheck {


//支持的文件类型

public static final List<String> ALLOW_TYPES = Arrays.asList("image/jpg","image/jpeg","image/png","image/gif");


//校验文件类型是否是被允许的

public static boolean allowUpload(String postfix){

return ALLOW_TYPES.contains(postfix);

}

}

6、核心Controller

public List<Map<String,String>> cutImgFun(HttpServletRequest request,

MultipartFile imgFile,Integer flag,Integer catalog) {


List<Map<String, String>> resultList = new ArrayList<>();

//剪裁图片坐标

String x = request.getParameter("x");

String y = request.getParameter("y");

String w = request.getParameter("w");

String h = request.getParameter("h");


//原始图片坐标

String boundx = request.getParameter("boundx");

String boundy = request.getParameter("boundy");


//切图参数

int imgeX = (int) Double.parseDouble(x);

int imgeY = (int) Double.parseDouble(y);

int imegW = (int) Double.parseDouble(w);

int imgeH = (int) Double.parseDouble(h);

int srcX = (int) Double.parseDouble(boundx);

int srcY = (int) Double.parseDouble(boundy);



//3.获取文件全名称

String originalFilename = imgFile.getOriginalFilename();

System.out.println("文件全名称" + originalFilename);

//4.获取后缀

String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);

System.out.println("后缀" + suffix);

//6.获取新的随机文件名

String newFileName = "";

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");

int num = (int) (Math.random() * 899) + 100;

newFileName = sdf.format(new Date()) + num;


try {

//处理头像附件

if (imgFile != null) {

//判断是否为图片文件

if (FileUploadCheck.allowUpload(imgFile.getContentType())) {

CutImgeUtil cutImgeUtil = new CutImgeUtil();

resultList = cutImgeUtil.cutImge(imgFile.getInputStream(), imgeX, imgeY, imegW, imgeH, srcX, srcY, newFileName, suffix, flag, catalog,IMG_SECURITY);

return resultList;


}

}else {

Map<String, String> map = new HashMap<String, String>();

map.put("errorInfo", "剪切失败...");

map.put("errorCode", "1");

resultList.add(map);

return resultList;

}


} catch (Exception e) {

e.printStackTrace();

logger.error("上传失败");

Map<String, String> map = new HashMap<String, String>();

map.put("errorInfo", "剪切失败...");

map.put("errorCode", "1");

resultList.add(map);

return resultList;

}


Map<String, String> map = new HashMap<String, String>();

map.put("errorInfo", "剪切失败...");

map.put("errorCode", "1");

resultList.add(map);

return resultList;


}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值