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;


}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
--------- shearphoto2.0 增强版升级概况 从shearphoto 1.5直接跳跃到shearphoto 2.0,这是shearphoto重大革新。本来我是想shearphoto 1.6 、1.7、 1.8 慢慢升的,但是这样升级只会让shearphoto慢慢走向灭亡!结果我又辛苦了一个多星期,把shearphoto 2.0升级完成! shearphoto2.0之前,我认为没必要加入HTML5,兼容IE6 7 8就够。但是直到后来!我知道这是我一个错误的决定 因为用户并没有为shearphoto 1.5埋单,原因shearphoto 1.5没有HTML5截取,用户觉得会增加服务器负载!而且又不是本地加载图片!我一个错误的决定!导致用户份额一直没有明显大增。 shearphoto 2.0是收集所有用户的意见开发而成的! 重大的特性就是全面支持HTML5 1:支持translate3d 硬件加速移动 2:加入图片预览功能 3:加入了压缩数码相机图片, 以及HTML5 canvas本地切图,截图 但依然继续支持IE6 7 8 哦!有人问IE6 7 8不兼容HTML5啊,你骗人吗? 先不要急!shearphoto 2.0的机制是这样的:有HTML5则使用HTML5 canvas切图,截图,JS先会截取一张最合理化的截图,然后交给后端,根据用户设置,进行压缩截图 没有HTML5的浏览器则采用先上传截取的策略,就是原先1.5的策略。 当然有些用户如果不喜欢HTML5,也可以根据接口自行关闭 4:加HTML5图片特效,就一如美图秀秀这样的特效!shearphoto一共提供14种漂亮特效,感谢腾讯AI对图片特效提供支持 shearphoto 2.0增添很多接口,大部份是HTML5的设置!请下载源码体验 shearphoto外忧内患,已经没退路了。在WEB截图界,shearphoto必须要干个第一!.shearphoto不再局限于头像截取,shearphoto更可用于商城的商品图片编辑。 shearphoto含HTML5图片压缩功能!一张十M 二十M的图,照样能帮你压成你要的容量和尺寸, 一般情况下!商城的商品图片都是通过数码相机拍摄后,要用PHOTOshop把数码相机内几十M的图片,压缩,截取,然后才能上传到商城服务器! 这样的操作是不是太麻烦了! 如果你使用shearphoto你就快捷很多了,shearphoto你只需要直接选择图片,就会帮你进行压缩截取上传,添加到数据库。这样的一条龙服务! shearphoto 2.0的机制是无可挑剔的!但是不排除有BUG存在,如果用户遇到BUG情况,请到论坛 或官方QQ群进行反馈,我会第一时间发布补丁! shearphoto支持PHP和JAVA,JAVA由网友所写,但是JAVA版并不是太完善,使用的是以前的shearphoto1.3!我 一直很想把NET python nodejs JAVA的很完善地做出来! 可惜个人能力有限,如果你喜欢shearphoto,你又会玩 NET python nodejs JAVA,又想为互联网做贡献,那么你可以加入shearphoto团队,把这些后端版本做出来。但shearphoto没有薪水给你! shearphoto免费开源的,没有利润可图,纯粹是抱着为互联网做贡献的心态!如果你跟我一样,请加入到shearphoto后端开发 浏览器支持: 兼容IE 6 及以上的所有浏览器 后端支持: 支持PHP5.X 至 PHP7.0或以上 支持JAVA后端(shearphoto1.3开发) 系统支持: 支持linux WINDOW服务器 shearphoto采用原生JS + 原生PHP所写,绝对不含JQ插件,对JQ情有独忠的,这个插件不合适你 2015 年 9月 5 日 shearphoto作者:明哥先生 版本号:shearphoto2.0 shearphoto官网:www.shearphoto.com shearphoto官方QQ群:461550716

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值