另外一个博客站点

纯 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 "";

    }
posted @ 2020-11-17 10:35  z-7  阅读(322)  评论(0编辑  收藏  举报
另外一个博客站点