Java使用Base64上传头像,并解决IOS上传图片角度问题
- H5代码
<div>
<img src="" alt="" id="user" />
<input type="file" id="file" onchange="onChange(event)" accept="image/*"/>
</div>
- Js
function onChange(event) {
var file = event.target.files[0];
// 图片方向角
var Orientation = null;
if (file) {
var rFilter = /^(image\/jpeg|image\/png)$/i; // 检查图片格式
if (!rFilter.test(file.type)) {
alert("请选择jpeg、png格式的图片");
return;
}
//获取照片方向角属性
EXIF.getData(file, function () {
EXIF.getAllTags(this);
Orientation = EXIF.getTag(this, 'Orientation');
});
}
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function (e) {
var result=reader.result;
var img = new Image();
img.src = e.target.result;
img.onload = function () {
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
const maxSize = 100 * 1024; //100K
const maxWidth = 640; //设置最大宽度
const maxHeight = maxWidth; //设置最大高度
canvas.width = img.width;
canvas.height = img.height;
//利用canvas进行绘图
context.drawImage(img, 0, 0);
//修复ios
switch(Orientation){
case 6://需要顺时针(向左)90度旋转
rotateImg(img,'left',canvas);
break;
case 8://需要逆时针(向右)90度旋转
rotateImg(img,'right',canvas);
break;
case 3://需要180度旋转
rotateImg(img,'right',canvas);//转两次
rotateImg(img,'right',canvas);
break;
}
var fileSize = calculaFileSize(img.src);
let nRate = getCompressRate(maxSize, fileSize);
//将原来图片的质量压缩到原先的0.2倍。
var data = canvas.toDataURL('image/jpeg', nRate) //data url的形式
fileSize = calculaFileSize(data);
imgDATA = data;
$("#myImage").attr("src", data);
var cwidth = img.width;
var cheight = img.height;
if (img.height > maxHeight) {
//按最大高度等比缩放
cwidth *= maxHeight / img.height;
cheight = maxHeight;
}
if (img.width > maxWidth) {
//按最大宽度等比缩放
cheight *= maxWidth / img.width;
cwidth = maxWidth;
}
uploadImg(imgDATA);//ajax方法,与后台交互
};
};
// reader.readAsDataURL(file);
}
function calculaFileSize(base64) {
// 计算base64文件流大小
base64 = base64.substring(22);
const equalIndex = base64.indexOf('=');
if (base64.indexOf('=') > 0) {
base64 = base64.substring(0, equalIndex);
}
var strLength = base64.length;
var fileLength = parseInt(strLength - (strLength / 8) * 2);
return fileLength;
}
function getCompressRate(allowMaxSize, fileSize) {
// 计算压缩比率,size单位为MB
let compressRate = 1;
if (fileSize / allowMaxSize > 10) {
compressRate = 0.4;
}else if (fileSize / allowMaxSize > 4) {
compressRate = 0.5;
} else if (fileSize / allowMaxSize > 3) {
compressRate = 0.6;
} else if (fileSize / allowMaxSize > 2) {
compressRate = 0.7;
} else if (fileSize > allowMaxSize) {
compressRate = 0.8;
} else {
compressRate = 0.9;
}
return compressRate;
}
//对图片旋转处理
function rotateImg(img, direction,canvas) {
//alert(img);
//最小与最大旋转方向,图片旋转4次后回到原方向
var min_step = 0;
var max_step = 3;
//var img = document.getElementById(pid);
if (img == null)return;
//img的高度和宽度不能在img元素隐藏后获取,否则会出错
var height = img.height;
var width = img.width;
//var step = img.getAttribute('step');
var step = 2;
if (step == null) {
step = min_step;
}
if (direction == 'right') {
step++;
//旋转到原位置,即超过最大值
step > max_step && (step = min_step);
} else {
step--;
step < min_step && (step = max_step);
}
//旋转角度以弧度值为参数
var degree = step * 90 * Math.PI / 180;
var ctx = canvas.getContext('2d');
switch (step) {
case 0:
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0);
break;
case 1:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, 0, -height);
break;
case 2:
canvas.width = width;
canvas.height = height;
ctx.rotate(degree);
ctx.drawImage(img, -width, -height);
break;
case 3:
canvas.width = height;
canvas.height = width;
ctx.rotate(degree);
ctx.drawImage(img, -width, 0);
break;
}
}
- ajax与后台交互
function uploadImg(img) {
var params = {
imgPath : img,//base64
_empid :_empid //上传头像用户的id
};
$.ajax({
url:"../../../uploadImg",
data:params,
type:"post",
success:function(data){
if(data.success==true){
$("#user").attr("src",imgUrl+data.url);
console.log(data.msg);
}else{
alert('头像上传失败,请稍后再试');
}
}
})
}
- Controller
@RequestMapping(value = "/../../uploadImg", produces = "text/html;charset=UTF-8")
@ResponseBody
public Object uploadImg(@RequestParam(value = "imgPath") String imgPath,
@RequestParam(value = "_empid") String userId, HttpServletRequest request)
throws InterruptedException, IOException {
JSONObject j = new JSONObject();
if ("".equals(imgPath) || imgPath == null) {
j.put("success", false);
j.put("msg", "图片传送失败");
}eles{
//调用ImgUtil工具类,返回图片的地址
String imgUrl=ImgUtil(imgUrl,request);
//将地址放入数据库中
}
return new Gson().toJson(doPostMap);
}
- ImgUtil工具类
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import sun.misc.BASE64Decoder;
public class ImgUtil {
public static String getImg(String imgUrl,HttpServletRequest request) throws IOException {
String realPath = request.getSession().getServletContext().getRealPath("/upload/");
System.out.println(realPath);
String imagePath = realPath+"\\";
System.out.println(imagePath);
String strImage=imgUrl;
File file=new File(imagePath);
if(!file .exists() && !file .isDirectory()){
file .mkdirs();
}
if(strImage.indexOf(',')>0){
String[] strBase64 = strImage.split(",");
if(strBase64 != null && strImage.length() >= 2){
strImage = strBase64[1];
}
}
BASE64Decoder decoder = new BASE64Decoder();
// Base64解码
byte[] bytes = decoder.decodeBuffer(strImage);
for (int i = 0; i < bytes.length; ++i) {
if (bytes[i] < 0) {// 调整异常数据
bytes[i] += 256;
}
}
// 生成jpeg图片
String fileName=java.util.UUID.randomUUID() + ".jpg";
OutputStream out = new FileOutputStream(imagePath+fileName);
out.write(bytes);
out.flush();
out.close();
return fileName;
}
}