纯 HTML加JS 压缩图片并上传 Java
最近在写移动端web项目,遇见一个上传图片的需求,一开始没有做任何优化,直接用ajax上传,结果就是被客户一顿臭叼,上传5张照片怎么要这么久 !啥玩意
后来做出优化,在PC端上传没毛病 嗖的一下就请求好了,在移动端上就 响应特别慢,目前的手机拍照图片大小都是很大的, 比如我的 华为P20拍一张HDR照片就已经将近10MB的内存了,PC使用的是宽带影响非常小,但是移动端就不能了。 不管是 把图片转为base64 编码传到后端,这个base64编码长度就已经是很大
最后想到 压缩图片,效果非常非常显著
效果图
1、HTML界面
2、上传前图片大小
3、上传后图片大小
效果是非常显著的,尤其是在移动端上面,速度提升非常明显。PC端使用的是带宽影响不大,图片的大小可以自己根据画布分辨率调,我这边是做一个案例
HTML代码
HTML head头加入
<meta http-equiv="Content-Type" content="multipart/form-data; charset=utf-8" />
引入canvas.js
<script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/canvasjs/1.7.0/canvasjs.min.js"></script>
引入Layui.js
<script src="https://www.layuicdn.com/auto/layui.js" v="layui" e="layui"" charset="utf-8"></script>
我前端使用的是Layui,除了样式组件不一样,压缩图片代码是通用的
<div class="layui-card-body">
<form class="layui-form" action="">
<div class="layui-form-item">
<label class="layui-form-label">图片描述</label>
<div class="layui-input-inline">
<textarea id="desc" placeholder="以上是某某某店铺VMD图片....." class="layui-textarea"></textarea>
</div>
</div>
</form>
<div class="layui-upload">
<button type="button" class="layui-btn layui-btn-fluid color3" id="img_select_click"> <i class="layui-icon"></i> 图片选择</button>
<button type="button" class="layui-btn layui-btn-fluid color3" style="margin-top: 10px;" id="ok_upload_click"> <i class="layui-icon"></i> 确定上传</button>
<!-- 准备一个 div块级元素 用来 装载img标签 -->
<div class="layui-upload-list" id="img_show_div"></div>
</div>
</div>
JS代码
JS代码=== //使用的 是 layui uplaod组件 非常好用,upload组件直接可以让我们简单的拿到图片base64编码地址
layui.use(['upload','layer'], function(){
var jQuery = layui.jquery,
upload = layui.upload,
layer = layui.layer;
//创建画布 canvas 用于存放压缩后的图片
var canvas = document.createElement('canvas');
//获取2D绘制对象
var context = canvas.getContext('2d');
//画布的宽 对等于压缩后的图片宽
canvas.width = 400;
//画布的高 对等于压缩后的图片高
canvas.height = 300;
upload.render({
elem: '#img_select_click'
,auto: false //取消选择图片后自动上传
,multiple: true //开启多选
,choose: function(obj){
//预读本地文件示例,不支持ie8
obj.preview(function(index, file, result){
//let length = files.length;
//files[length]=file;
//选择文件后 在div元素创建img标签显示图片
// index 多选图片时 返回下标
// file 具体file对象
// result 图片的 base64 的图片地址
//创建img标签到html上预览图片
jQuery('#img_show_div').append('<img src="'+ result +'" alt="'+ file.name +'" class="layui-upload-img img1" onclick="showImg(this)" >')
});
}
});
//确认上传按钮
jQuery('#ok_upload_click').on('click',function(){
var imgs = jQuery('img');//得到所有img标签对象
//因为是可多选图片 循环遍历得到img 对象
//循环外面还可以实现做进度条,for循环完成上传后进度条到100%
for(let i = 0;i<imgs.length;i++){
//得到img的 base64 图片地址
let src_ = imgs[i].src;
//截取图片类型 image/jpg 等等
let imgType = src_.substring(src_.indexOf(':')+1,src_.indexOf(';'));
//清除画布内容画布
context.clearRect(0, 0, 400, 300);
//绘制图片 imgs[i] 是 img图片标签
context.drawImage(imgs[i],0,0,400,300);
//将画布中的图片 转为 二进制 blob文件对象 传参到 java 后端,使用 MultipartFile 类绑定
canvas.toBlob(function (blob) {
//使用 formData形式传递 ,不能用json格式 否则会报类型转换错误!!
let formData = new FormData();
formData.append('file',blob); //file对象
jQuery.ajax({
url:"/O2OSALE2/wx/vmdtest.json", //请求的url地址
dataType:"json", //返回格式为json
async:true,//请求是否异步,默认为异步,这也是ajax重要特性
data: formData, //参数值
type:"POST", //请求方式
processData : false, // 使数据不做处理!很重要
contentType : false, // 不要设置Content-Type请求头!很重要
success:function(req){
//请求成功时处理
console.log(req);
},
error:function(){
//请求出错处理
layer.msg('上传失败!!', {icon: 5});
}
});
},imgType);
}
});
});
JAVA代码
@RequestMapping(value = { "/vmdTest.json" })
@ResponseBody
public String upload(@RequestParam MultipartFile file) {
System.out.println("文件名称==="+file.getName());
System.out.println("完整文件==="+file);
return "";
}