点滴记载,点滴进步,愿自己更上一层楼。
最近公司用到手机端上传图片,些许不顺,在此记录下以便以后再碰到不用狂找资料。
现在手机像素都挺高,拍一张照片都挺大,这里上传图片用到了一个插件,专门用来压缩图片,然后后台在进行解码,转成图片然后显示到前台。
插件源码:https://github.com/think2011/localResizeIMG
工具:idea 浏览器 手机
语言:java JavaScript
框架:springmvc jquery
环境搭建可以参照:springmvc入门---框架搭建
进入正题:
原理:前台选图片上传,插件压缩成一个字符串,ajax提交这个压缩后的图片到后台,后台进行解码,写入到磁盘。
因为要用到ajax提交,所以有些设置还需要 两个jar文件。
jackson-core-asl-1.9.13.jar
jackson-mapper-asl-1.9.13.jar
pom依赖:
<!-- json转换jar包 start -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<!-- json转换jar包 end -->
具体可以参照:
springmvc----json参数绑定
注释下的挺清晰,不在多余赘述,直接上代码。
<%@ 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"%>
<!DOCTYPE html>
<html>
<head>
<title>移动端上传图片实现</title>
</head>
<body>
<%--上传控件--%>
<input type="file" id="fileUpload" accept="image/*">
<%--这里用来显示图片用--%>
<div id="imgFiles"></div>
</body>
<%--引入插件包--%>
<script src="/static/upload/lrz.bundle.all.js"></script>
<%--引入自己写的js用来控制压缩上传等操作--%>
<script src="/static/mobile/mobileUpload.js"></script>
<%--jquery--%>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
</html>
mobileUpload.js
document.querySelector('#fileUpload').addEventListener('change', function () {
lrz(this.files[0])
.then(function (rst) {
// 处理成功会执行
uploadFile(rst);
})
.catch(function (err) {
// 处理失败会执行
})
.always(function () {
// 不管是成功失败,都会执行
});
});
// 因为压缩后的图片为一串字符串,所以这里用普通的ajax提交就行
function uploadFile(rst){
$.ajax({
type: "post",
url: "/imageUpload",
async: false,
data: {base64Str:rst.base64},
dataType: "json",
success: function (data) {
if(data.status == "success"){
// 将上传好的图片显示到页面中
var imgPath = "<img src='/pic/"+data.data+"' style='width: 100px;height: 100px;'>";
$('#imgFiles').append(imgPath);
}else if(data.status == "error"){
}
}
});
}
后台
@RequestMapping(value = "/imageUpload")
@ResponseBody
public ResultVo imageUpload(String base64Str){
ResultVo result = new ResultVo();
try{
// 本地方图片路径
String localImgPath = "D:\\soft\\tomcatTempFile\\";
// 用于做图片名字
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS");
// 解码后图片名称
String imgName = df.format(new Date())+".jpg";
// 解码
byte[] base64Byte = getBase64PhotoBytes(base64Str);
File tmpFile = new File(localImgPath + imgName);
byteArrUpload(base64Byte, tmpFile);
result.setStatus("success");
result.setData(imgName);
return result;
}catch (Exception e){
result.setStatus("error");
return result;
}
}
/**
* 手机端上传图片,由于图片过大,所有都是通过压缩的,压缩后为base64 字节码,这里进行解码。
*
* @return
* @throws Exception
*/
private byte[] getBase64PhotoBytes(String mobilePhotosbase64) throws Exception {
BASE64Decoder decoder = new BASE64Decoder();
// 获得一个图片文件流,我这里是从flex中传过来的
byte[] result = decoder.decodeBuffer(mobilePhotosbase64.split(",")[1]);//解码
for (int index = 0; index < result.length; ++index) {
if (result[index] < 0) {// 调整异常数据
result[index] += 256;
}
}
return result;
}
/**
* 上传文件
*
* @param imgBytes 解码后的图片信息
* @param dst 目标文件
*/
private void byteArrUpload(byte[] imgBytes, File dst) {
try {
OutputStream out = null;
try {
out = new BufferedOutputStream(new FileOutputStream(dst));
out.write(imgBytes);
out.flush();
} finally {
out.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
ReturnVo.java
public class ResultVo<T> {
private String status;
private T data;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
测试:
1 浏览器模拟手机端测试结果:
要上传的图片
上传后jsp显示
本地保存图片文件夹
2 手机测试结果
要上传的图片
手机端显示
本地图片保存路径的文件
据测试兼容性不错。再次记录。记录完毕。