直入正题
原理:通过 base64编码 进行互转 (图片 --- 字符串)
1、jsp页面代码(复制即行)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<c:set value="${pageContext.request.contextPath}" scope="page" var="ctx"></c:set>
<html>
<head>
<title>My JSP'libbbbbb.jsp'page</title>
<link rel="stylesheet" href="${ctx}/CQW/cropbox.css" type="text/css"></link>
</head>
<body>
<!-- 头像图片 -->
<div style="">
<div id="editImageDiv">
<div class="container" style="width: 400px; margin-right: 300px;">
<div class="imageBox">
<div class="thumbBox"></div>
<div class="spinner" style=""></div>
</div>
<div class="action">
<div class="new-contentarea tc">
<a href="javascript:void(0)" class="upload-img">
<i class="fa fa-image"></i>
<label for="upload-file">请先选择图片...</label>
</a>
<input type="text" hidden="hidden" name="signupId" value="${signuptable.signupId}"/>
<input type="file" class="" name="upload_file" id="upload-file">
</div>
<input type="button" id="btnCrop" class="Btnsty_peyton2" value="保存">
<input type="button" id="btnZoomIn" class="Btnsty_peyton" value="+">
<input type="button" id="btnZoomOut" class="Btnsty_peyton" value="-">
</div>
<div class="cropped"></div>
</div>
</div>
<!-- 图片 -->
</div>
<script type="text/javascript" src="${ctx}/CQW/jquery.js"></script>
<script type="text/javascript" src="${ctx}/CQW/bootstrap.js"></script>
<script type="text/javascript" src="${ctx}/CQW/cropbox.js"></script> <%-- 必须 --%>
<script >
var image ="";
$(window).load(function() {
var options = {
thumbBox: '.thumbBox',
spinner: '.spinner',
imgSrc: ''
}
var cropper = $('.imageBox').cropbox(options);
var img = "";
$('#upload-file').on('change', function() {
var reader = new FileReader();
reader.onload = function(e) {
options.imgSrc = e.target.result;
cropper = $('.imageBox').cropbox(options);
}
reader.readAsDataURL(this.files[0]);
this.files = [];
getImg();
})
$('#btnCrop').on('click', function() {
image = cropper.getDataURL();
$.ajax(
{
url:"${ctx}/securityXXweb/bbbbb.do",
data: {imagea:image},
dataType:"json",
type:"POST",//必须post get提交数据有限制
success:function(data)
{
//1.成功的处理
if (data.state == true) {
alert("上传成功!");
} else {
alert("上传失败!");
}
}
});
})
function getImg() {
img = cropper.getDataURL();
$('.cropped').html('');
$('.cropped').append('<img src="' + img + '" align="absmiddle" style="width:180px;margin-top:4px;border-radius:180px;box-shadow:0px 0px 12px #7E7E7E;"><p>180px*180px</p>');
$('.cropped').append('<img src="' + img + '" align="absmiddle" style="width:128px;margin-top:4px;border-radius:128px;box-shadow:0px 0px 12px #7E7E7E;"><p>128px*128px</p>');
$('.cropped').append('<img src="' + img + '" align="absmiddle" style="width:64px;margin-top:4px;border-radius:64px;box-shadow:0px 0px 12px #7E7E7E;" ><p>64px*64px</p>');
}
$(".imageBox").on("mouseup", function() {
getImg();
});
$('#btnZoomIn').on('click', function() {
cropper.zoomIn();
})
$('#btnZoomOut').on('click', function() {
cropper.zoomOut();
})
});
</script>
</body>
</html>
1.1、 css样式代码 cropbox.css
@charset "utf-8";
.container {
width: 400px;
margin: 40px 147px 80px 147px;
position: relative;
font-family: 微软雅黑;
font-size: 12px;
}
.container p {
line-height: 12px;
line-height: 0px;
height: 0px;
margin: 10px;
color: #bbb
}
.action {
width: 400px;
height: 30px;
margin-top: 32px;
}
.cropped {
position: absolute;
right: -230px;
top: 0;
width: 200px;
border: 1px #ddd solid;
height: 460px;
padding: 4px;
text-align: center;
}
.imageBox {
position: relative;
height: 400px;
width: 400px;
border: 1px solid #aaa;
background: #fff;
overflow: hidden;
background-repeat: no-repeat;
cursor: move;
}
.imageBox .thumbBox {
position: absolute;
top: 50%;
left: 50%;
width: 200px;
height: 200px;
margin-top: -100px;
border-radius: 200px;
margin-left: -100px;
box-sizing: border-box;
border: 1px solid rgb(102, 102, 102);
box-shadow: 0 0 0 1000px rgba(0, 0, 0, 0.5);
background: none repeat scroll 0% 0% transparent;
}
.imageBox .spinner {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
text-align: center;
line-height: 400px;
color: #2F2A2A;
background: rgba(213, 211, 211, 0.7);
}
.Btnsty_peyton {
float: right;
width: 40px;
display: inline-block;
margin-bottom: 10px;
height: 36px;
line-height: 32px;
font-size: 14px;
color: #666666;
margin: 0px 2px;
background: -moz-linear-gradient( top, #ffffff, #f5f5f5);
/* border-radius: 3px;*/
text-decoration: none;
cursor: pointer;
border: 1px solid #efefef;
/*box-shadow: 0px 0px 5px #B0B0B0;*/
/*border: 0px #fff solid;*/
}
.Btnsty_peyton2 {
float: right;
width: 70px;
display: inline-block;
margin-bottom: 10px;
height: 36px;
line-height: 32px;
font-size: 14px;
color: #ffffff;
margin: 0px 2px;
background-color: #ff7900;
/* border-radius: 3px;*/
text-decoration: none;
cursor: pointer;
border: 1px solid #efefef;
/*box-shadow: 0px 0px 5px #B0B0B0;*/
/*border: 0px #fff solid;*/
}
/*选择文件上传*/
.new-contentarea {
width: 165px;
overflow: hidden;
margin: 0 auto;
position: relative;
float: left;
}
.new-contentarea label {
width: 100%;
height: 100%;
display: block;
}
.new-contentarea input[type=file] {
width: 188px;
height: 50px;
background: #333;
margin: 0 auto;
position: absolute;
right: 50%;
margin-right: -94px;
top: 0;
right
/*\**/
: 0px\9;
margin-right
/*\**/
: 0px\9;
width
/*\**/
: 10px\9;
opacity: 0;
filter: alpha(opacity=0);
z-index: 2;
cursor: pointer;
}
a.upload-img {
width: 200px;
display: inline-block;
margin-bottom: 10px;
height: 36px;
line-height: 36px;
font-size: 14px;
color: #666666;
border-radius: 3px;
text-decoration: none;
cursor: pointer;
border: 0px #fff solid;
}
a.upload-img:hover {
background-color: #ec7e70;
cursor: pointer;
}
a.upload-img i {
float: left;
line-height: 36px;
font-size: 18px;
color: #ff7900;
margin: 0px 15px;
}
a.upload-img label {
font-weight: normal;
}
.tc {
height: 36px;
line-height: 36px;
border: 1px solid #efefef;
margin-top: -1px;
}
1.2、 js样式代码 cropbox.js 其他的 (jquery.js 、bootstrap.js 是公用的,上网搜即可)
/**
*
*/
"use strict";
(function (factory) {
if (typeof define === 'function' && define.amd) {
define(['jquery'], factory);
} else {
factory(jQuery);
}
}(function ($) {
var cropbox = function(options, el){
var el = el || $(options.imageBox),
obj =
{
state : {},
ratio : 1,
options : options,
imageBox : el,
thumbBox : el.find(options.thumbBox),
spinner : el.find(options.spinner),
image : new Image(),
getDataURL: function ()
{
var width = this.thumbBox.width(),
height = this.thumbBox.height(),
canvas = document.createElement("canvas"),
dim = el.css('background-position').split(' '),
size = el.css('background-size').split(' '),
dx = parseInt(dim[0]) - el.width()/2 + width/2,
dy = parseInt(dim[1]) - el.height()/2 + height/2,
dw = parseInt(size[0]),
dh = parseInt(size[1]),
sh = parseInt(this.image.height),
sw = parseInt(this.image.width);
canvas.width = width;
canvas.height = height;
var context = canvas.getContext("2d");
context.drawImage(this.image, 0, 0, sw, sh, dx, dy, dw, dh);
var imageData = canvas.toDataURL('image/png');
return imageData;
},
getBlob: function()
{
var imageData = this.getDataURL();
var b64 = imageData.replace('data:image/png;base64,','');
var binary = atob(b64);
var array = [];
for (var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], {type: 'image/png'});
},
zoomIn: function ()
{
this.ratio*=1.1;
setBackground();
},
zoomOut: function ()
{
this.ratio*=0.9;
setBackground();
}
},
setBackground = function()
{
var w = parseInt(obj.image.width)*obj.ratio;
var h = parseInt(obj.image.height)*obj.ratio;
var pw = (el.width() - w) / 2;
var ph = (el.height() - h) / 2;
/*
'background-size': w/3.18 +'px ' + h/3.18 + 'px',
'background-position': pw/1.75 + 'px ' + ph/1.75 + 'px',
*/
el.css({
'background-image': 'url(' + obj.image.src + ')',
'background-size': w +'px ' + h + 'px',
'background-position': pw + 'px ' + ph + 'px',
'background-repeat': 'no-repeat'});
},
imgMouseDown = function(e)
{
e.stopImmediatePropagation();
obj.state.dragable = true;
obj.state.mouseX = e.clientX;
obj.state.mouseY = e.clientY;
},
imgMouseMove = function(e)
{
e.stopImmediatePropagation();
if (obj.state.dragable)
{
var x = e.clientX - obj.state.mouseX;
var y = e.clientY - obj.state.mouseY;
var bg = el.css('background-position').split(' ');
var bgX = x + parseInt(bg[0]);
var bgY = y + parseInt(bg[1]);
el.css('background-position', bgX +'px ' + bgY + 'px');
obj.state.mouseX = e.clientX;
obj.state.mouseY = e.clientY;
}
},
imgMouseUp = function(e)
{
e.stopImmediatePropagation();
obj.state.dragable = false;
},
zoomImage = function(e)
{
e.originalEvent.wheelDelta > 0 || e.originalEvent.detail < 0 ? obj.ratio*=1.1 : obj.ratio*=0.9;
setBackground();
}
obj.spinner.show();
obj.image.onload = function() {
obj.spinner.hide();
setBackground();
el.bind('mousedown', imgMouseDown);
el.bind('mousemove', imgMouseMove);
$(window).bind('mouseup', imgMouseUp);
el.bind('mousewheel DOMMouseScroll', zoomImage);
};
obj.image.src = options.imgSrc;
el.on('remove', function(){$(window).unbind('mouseup', imgMouseUp)});
return obj;
};
jQuery.fn.cropbox = function(options){
return new cropbox(options, this);
};
}));
2、Controller服务层
@RequestMapping("/lissss")
public String lissss(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
return "/libbbbbb";//跳转界面
}
//修改图片bbbbbbbbbbbb
@ResponseBody
@RequestMapping(value="/bbbbb",produces="application/json")
public Object bbbbb(HttpServletRequest req){
JsonReturn jsonReturn = new JsonReturn();
jsonReturn.setState(false);
HttpSession session=req.getSession();
Signuptable tabel =(Signuptable) session.getAttribute("SESSION_USER");//获取登录时保存到session的用户数据
//如果目录不存在就创建
String uploadPath = "E:\\upload\\lis";
File uploadDir=new File(uploadPath);
if (!uploadDir.exists()) {
uploadDir.mkdir();
}
String strimagea=req.getParameter("imagea");//获取ajax提交过来的字符串(图片的编码格式)
//不过需要注意的是,一般插件返回的base64编码的字符串都是有一个前缀的。"data:image/jpeg;base64," 最后用逗号区分 解码之前这个得去掉。
String[] arlstr = strimagea.split(",");//切割获取后部分
String ccdff=arlstr[1];
String tpMCQ=System.nanoTime()+".jpg";
//先尝试保存
try{
generateImage(ccdff, "E:/upload/lis/"+tpMCQ);//将base64编码字符串转换为图片
jsonReturn.setState(true);
}catch (Exception e) {
jsonReturn.setState(false);
}
if(jsonReturn.getState()){
Signuptable Signup=new Signuptable();
Signup.setSignupId(tabel.getSignupId());
Signup.setHeadportrait(tpMCQ);//图片 需要进行判断
boolean bolS = signupService.updatetable(Signup);//只需要会员ID 和 图片名称
if(bolS){//重写SESSION_USER 值(图片问题需要重写)
try{//删除旧图片
String oldFilePath = uploadPath + File.separator+ tabel.getHeadportrait();
File oldFile = new File(oldFilePath);
if (oldFile.exists() && oldFile.isFile()) {
oldFile.delete();
}
}catch (Exception e) { }
Signuptable Signupcx=new Signuptable();
Signupcx=tabel;
Signupcx.setHeadportrait(tpMCQ);
session.setAttribute("SESSION_USER",Signupcx);
}
}else{
// 删除刚新增的图片
String oldFilePath = uploadPath + File.separator+ tpMCQ;
File oldFile = new File(oldFilePath);
if (oldFile.exists() && oldFile.isFile()) {
oldFile.delete();
}
}
return JSONSerializer.toJSON(jsonReturn);//需要引用架包文件lib里
}
/**
* @Description: 将base64编码字符串转换为图片
* @Author:
* @CreateTime:
* @param imgStr base64编码字符串
* @param path 图片路径-具体到文件
* @return
*/
public static boolean generateImage(String imgStr, String path) {
if (imgStr == null){
return false;
}
// 不过需要注意的是,一般插件返回的base64编码的字符串都是有一个前缀的。
// "data:image/jpeg;base64," 解码之前这个得去掉。
BASE64Decoder decoder = new BASE64Decoder();
try {
// 解密
byte[] b = decoder.decodeBuffer(imgStr);
// 处理数据
for (int i = 0; i < b.length; ++i) {
if (b[i] < 0) {
b[i] += 256;
}
}
OutputStream out = new FileOutputStream(path);
out.write(b);
out.flush();
out.close();
return true;
} catch (Exception e) {
return false;
}
}
/** 在这不用,只是写下 图片换为base64编码字符串 这个在页面js 有写到
* @Description: 根据图片地址转换为base64编码字符串
* @Author:
* @CreateTime:
* @return
*/
public static String getImageStr(String imgFile) {
InputStream inputStream = null;
byte[] data = null;
try {
inputStream = new FileInputStream(imgFile);
data = new byte[inputStream.available()];
inputStream.read(data);
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
// 加密
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(data);
}
最后保存时有个错误提示 ,但不影响功能。(新手勿喷)