weui上传多图片,压缩,base64编码的示例代码


Posted in Javascript onJune 22, 2020

记录一下在做一个报修功能的心路历程,需求功能很简单,一个表单提交,表单包含简单的文字字段以及图片

因为使用的是weui框架,前面的话去找weui的表单和图片上传组件,说实话,weui的组件写的还不错,作为一个不太懂前端的渣渣可以拿来开箱即用

主要是不用调那么多的样式问题,直接上代码:

<div class="weui-cell">
 <div class="weui-cell__bd">
  <div class="weui-uploader">
   <div class="weui-uploader__hd">
    <p class="weui-uploader__title">图片上传</p>
    <!--      <div class="weui-uploader__info">0/2</div>-->
   </div>
   <div class="weui-uploader__bd">
    <ul class="weui-uploader__files" id="uploaderFiles">
     <!--<li class="weui-uploader__file" style="background-image:url(/img/upload-btn.png)"></li>
     <li class="weui-uploader__file weui-uploader__file_status" style="background-image:url(/img/upload-btn.png)">
      <div class="weui-uploader__file-content">
       <i class="weui-icon-warn"></i>
      </div>
     </li>
     <li class="weui-uploader__file weui-uploader__file_status" style="background-image:url(/img/upload-btn.png)">
      <div class="weui-uploader__file-content">50%</div>
     </li>-->
    </ul>
    <div class="weui-uploader__input-box">
     <input id="uploaderInput" class="weui-uploader__input zjxfjs_file" type="file" accept="image/*" multiple="">
    </div>
   </div>
  </div>
 </div>
</div>
//文件上传js
var tmpl = '<li class="weui-uploader__file" style="background-image:url(#url#)"></li>',
 $gallery = $("#gallery"),
 $galleryImg = $("#galleryImg"),
 $uploaderInput = $("#uploaderInput"),
 $uploaderFiles = $("#uploaderFiles");
$uploaderInput.on("change", function(e) {
 var src, url = window.URL || window.webkitURL || window.mozURL,
  files = e.target.files;
 //这里获取到批量的file
 var fileNum =fileArr.length;
 for(var i = 0, len = files.length; i < len; ++i) {
  var file = files[i];
  if(fileNum + i + 1 > 5) {
   break;
  }
  // fileArr.push(file);
  if(url) {
   src = url.createObjectURL(file);
  } else {
   src = e.target.result;
  }
  var reader = new FileReader()
  reader.readAsDataURL(file)
  reader.onload = function(e) {
   var image = new Image() //新建一个img标签(还没嵌入DOM节点)
   image.src = e.target.result
   image.onload = function () {
    var canvas = document.createElement('canvas'),
     context = canvas.getContext('2d'),
     imageWidth = image.width / 5.5, //压缩后图片的大小
     imageHeight = image.height / 5.5;
    canvas.width = imageWidth;
    canvas.height = imageHeight;
    context.drawImage(image, 0, 0, imageWidth, imageHeight);

    var data = {
     base64: canvas.toDataURL('image/jpeg')
    }
    mui.ajax({
     url: "/file/uploadBase64",
     type: "POST",
     async: false,
     cache: false,
     processData: false,// 不处理发送的数据
     headers: {
      'Content-Type': 'application/json'
     },
     data: JSON.stringify(data),
     success: function(res){
      console.log(res)
      if (res.code==100){
       fileArr.push(res.data);
       //上传完成,前端页面显示
       $uploaderFiles.append($(tmpl.replace('#url#', canvas.toDataURL('image/jpeg'))));
      }else {
       weui.toast("出错了,请稍后再试", "forbidden");
      }
     },
     error:function () {
      weui.toast("出错了,请稍后再试", "forbidden");
     }
    });
   }
  }
 }
 checkPhotoSize();
});
//控制显示5张以内照片
function checkPhotoSize(){
 if(fileArr.length>4){
  $(".weui-uploader__input-box").hide();
 }else{
  $(".weui-uploader__input-box").show();
 }
}
var index; //第几张图片
$uploaderFiles.on("click", "li", function() {
 index = $(this).index();
 $galleryImg.attr("style", this.getAttribute("style"));
 $gallery.fadeIn(100);
});
$gallery.on("click", function() {
 $gallery.fadeOut(100);
});
//删除图片 删除图片的代码也贴出来。
$(".weui-gallery__del").click(function() {
 console.log('删除'+index);
 $uploaderFiles.find("li").eq(index).remove();
 fileArr.splice(index,1);
 checkPhotoSize();
});

这里有几个要注意的点

1、要实现多图片上传,对比了几个UI框架,感觉还是weui的样式做的最好看

2、考虑到图片大小问题,一开始我使用的是直接将图片文件以数组的形式post给后台,然后后台使用MultipartFile 数组接收,但是这导致有个问题,现在的手机拍照的图片都比较大,随便都有个3-5M一张图片,如果直接post给后台,用户体验不好(速度太慢了),同时也占用了服务器太多资源(主要是带宽和存储空间),所以必须前端先压缩后再上传

3、前端压缩目前能想到的是使用第三方工具接口(阿里或者七牛云端接口);前端页面利用canvas,进行base64编码,然后发送给后端,显然用后者会比较合适

最后利用canvas将图片进行base64编码压缩,可以实现到将3-5M的图片图片压缩为100k内,目前实现的是每次上传图片都会保存在服务器上,删除图片的话没法同步删除服务器上的图片,但是这个问题不大,需要修改的话将这个上传服务器的请求搞到点击提交表单的时候再上传图片就好了

最后贴一下后端接收代码:

/**
  * 上传图片信息,base64字符串格式
  * @param map
  * @param model
  * @return
  */
 @PostMapping(value = "uploadBase64")
 @ResponseBody
 public Map<String, Object> uploadBase64Image(@RequestBody Map<String, Object> map) throws ParseException, IOException {
  Map<String, Object> imageMap = new HashMap<>();
  String base64 = map.get("base64").toString();
  MultipartFile file = BASE64DecodedMultipartFile.base64ToMultipart(base64);
  //获取文件保存路径
  String fileSavePath = globalConfService.getByKey(StaticConfigUtil.FILE_SAVE_PATH).getConfValue();
  String fileServerPath = globalConfService.getByKey(StaticConfigUtil.FILE_SERVER_PATH).getConfValue();
  fileSavePath = fileSavePath + DateUtil.formatDatetime("yyyy-MM-dd");
  fileServerPath = fileServerPath + DateUtil.formatDatetime("yyyy-MM-dd");
  if (!file.isEmpty()) {

   String fileName = file.getOriginalFilename();
   String ext=fileName.substring(fileName.lastIndexOf(".")+1);

   String imgName = "/"+UUID.randomUUID()+ "." +ext;

   InputStream in = null;
   OutputStream out = null;
   try {
    File serverFile = new File(fileSavePath+imgName);
    //判断文件父目录是否存在
    if(!serverFile.getParentFile().exists()){
     serverFile.getParentFile().mkdir();
    }
    if (!serverFile.exists()) {
     serverFile.createNewFile();
    }
    in = file.getInputStream();
    out = new FileOutputStream(serverFile);
    byte[] b = new byte[1024];
    int len = 0;
    while ((len = in.read(b))!=-1) {
     out.write(b, 0, len);
    }
    out.close();
    in.close();
    String serverPath = fileServerPath + imgName;
    return ResultUtil.successJson(serverPath);
   } catch (Exception e) {
    e.printStackTrace();
    return ResultUtil.errorJson(ErrorEnum.E_40001,e.getMessage());
   } finally {
    if (out != null) {
     out.close();
     out = null;
    }
    if (in != null) {
     in.close();
     in = null;
    }
   }
  } else {
   return ResultUtil.errorJson(ErrorEnum.E_90007);
  }
 }
/**
 * base64转MultipartFile文件
 *
 * @param base64
 * @return
 */
public static MultipartFile base64ToMultipart(String base64) {
 try {
  String[] baseStrs = base64.split(",");

  BASE64Decoder decoder = new BASE64Decoder();
  byte[] b = new byte[0];
  b = decoder.decodeBuffer(baseStrs[1]);

  for (int i = 0; i < b.length; ++i) {
   if (b[i] < 0) {
    b[i] += 256;
   }
  }

  return new BASE64DecodedMultipartFile(b, baseStrs[0]);
 } catch (IOException e) {
  e.printStackTrace();
  return null;
 }
}

总结

到此这篇关于weui上传多图片,压缩,base64编码的示例代码的文章就介绍到这了,更多相关Weui多图片压缩上传内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
JavaScript Event学习第五章 高级事件注册模型
Feb 07 Javascript
iphone safari不支持position fixed的解决方法
May 04 Javascript
Javascript基础教程之函数对象和属性
Jan 18 Javascript
Bootstrap入门书籍之(四)菜单、按钮及导航
Feb 17 Javascript
jQuery实现简单的DIV拖动效果
Feb 19 Javascript
javascript验证手机号和实现星号(*)代替实例
Aug 16 Javascript
AngularJS操作键值对象类似java的hashmap(填坑小结)
Nov 12 Javascript
js获取html页面代码中图片地址的实现代码
Mar 05 Javascript
详解基于node.js的脚手架工具开发经历
Jan 28 Javascript
es6中比较有用的7个技巧小结
Jul 12 Javascript
微信小程序云开发获取文件夹下所有文件(推荐)
Nov 14 Javascript
使用 Vue-TCB 快速在 Vue 应用中接入云开发的方法
Feb 10 Javascript
详细分析Node.js 多进程
Jun 22 #Javascript
详细分析vue响应式原理
Jun 22 #Javascript
Vue循环遍历选项赋值到对应控件的实现方法
Jun 22 #Javascript
如何解决jQuery 和其他JS库的冲突
Jun 22 #jQuery
解决Vue 给mapState中定义的属性赋值报错的问题
Jun 22 #Javascript
支付宝小程序实现省市区三级联动
Jun 21 #Javascript
微信小程序实现canvas分享朋友圈海报
Jun 21 #Javascript
You might like
php中sql注入漏洞示例 sql注入漏洞修复
2014/01/24 PHP
ThinkPHP快速入门实例教程之数据分页
2014/07/01 PHP
phpword插件导出word文件时中文乱码问题处理方案
2014/08/19 PHP
php插入排序法实现数组排序实例
2015/02/16 PHP
推荐十款免费 WordPress 插件
2015/03/24 PHP
基于ThinkPHP5.0实现图片上传插件
2017/09/25 PHP
20个非常有用的PHP类库 加速php开发
2010/01/15 Javascript
Confirmer JQuery确认对话框组件
2010/06/09 Javascript
关于div自适应高度/左右高度自适应一致的js代码
2013/03/22 Javascript
JavaScript获取数组最小值和最大值的方法
2015/06/09 Javascript
微信JS-SDK自定义分享功能实例详解【分享给朋友/分享到朋友圈】
2016/11/25 Javascript
利用jQuery来动态为属性添加或者删除属性的简单方法
2016/12/02 Javascript
js 动态生成html 触发事件传参字符转义的实例
2017/02/14 Javascript
webpack结合express实现自动刷新的方法
2019/05/07 Javascript
jQuery事件模型默认行为执行顺序及trigger()与 triggerHandler()比较实例分析
2020/04/30 jQuery
使用python调用浏览器并打开一个网址的例子
2014/06/05 Python
python实现多线程的方式及多条命令并发执行
2016/06/07 Python
在win和Linux系统中python命令行运行的不同
2016/07/03 Python
python排序函数sort()与sorted()的区别
2018/09/18 Python
对python文件读写的缓冲行为详解
2019/02/13 Python
Python面向对象之继承和多态用法分析
2019/06/08 Python
python3+django2开发一个简单的人员管理系统过程详解
2019/07/23 Python
Python中base64与xml取值结合问题
2019/12/22 Python
代码总结Python2 和 Python3 字符串的区别
2020/01/28 Python
keras 实现轻量级网络ShuffleNet教程
2020/06/19 Python
Pyqt助手安装PyQt5帮助文档过程图解
2020/11/20 Python
美国轮胎网站:Priority Tire
2018/11/28 全球购物
FC-Moto美国:欧洲最大的摩托车服装和头盔商店之一
2019/08/24 全球购物
Fenty Beauty官网:蕾哈娜创立的美妆品牌
2021/01/07 全球购物
服装公司总经理岗位职责
2013/11/30 职场文书
劳动实践课感言
2014/02/01 职场文书
语文教研活动总结
2014/07/02 职场文书
2014年小学体育工作总结
2014/12/11 职场文书
初中学生操行评语
2014/12/26 职场文书
白鹤梁导游词
2015/02/06 职场文书
Java日常练习题,每天进步一点点(38)
2021/07/26 Java/Android