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 相关文章推荐
js下用层来实现select的title提示属性
Feb 23 Javascript
js中的onchange和onpropertychange (onchange无效的解决方法)
Mar 08 Javascript
JS动态添加Table的TR,TD实现方法
Jan 28 Javascript
怎么通过onclick事件获取js函数返回值(代码少)
Jul 28 Javascript
基于JavaScript实现动态添加删除表格的行
Feb 01 Javascript
JS作为值的函数用法示例
Jun 20 Javascript
JQuery学习总结【二】
Dec 01 Javascript
jQuery.Validate表单验证插件的使用示例详解
Jan 04 Javascript
Vue学习之路之登录注册实例代码
Jul 06 Javascript
Bootstrap弹出框(Popover)被挤压的问题小结
Jul 11 Javascript
过滤器vue.filters的使用方法实现
Sep 18 Javascript
详解CocosCreator项目结构机制
Apr 14 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将DateTime对象转化为友好时间显示的实现代码
2011/09/20 PHP
php中通过curl smtp发送邮件
2012/06/05 PHP
PHP入门教程之面向对象的特性分析(继承,多态,接口,抽象类,抽象方法等)
2016/09/11 PHP
详解PHP使用Redis存储session时的一个Warning定位
2017/07/05 PHP
PHP判断是否是微信打开还是浏览器打开的方法
2019/02/27 PHP
从URL中提取参数与将对象转换为URL查询参数的实现代码
2012/01/12 Javascript
网页广告中JS代码的信息监听示例
2014/04/02 Javascript
使用JavaScript刷新网页的方法
2015/06/04 Javascript
js制作带有遮罩弹出层实现登录注册表单特效代码分享
2015/09/05 Javascript
jQuery实用技巧必备(下)
2015/11/03 Javascript
javascript中checkbox使用方法简单实例演示
2015/11/17 Javascript
理解Angular数据双向绑定
2016/01/10 Javascript
JavaScript事件学习小结(五)js中事件类型之鼠标事件
2016/06/09 Javascript
详解Angular4中路由Router类的跳转navigate
2017/06/09 Javascript
NodeJS 中Stream 的基本使用
2018/07/30 NodeJs
React 源码中的依赖注入方法
2018/11/07 Javascript
Vue+ElementUI使用vue-pdf实现预览功能
2019/11/26 Javascript
vue仿淘宝滑动验证码功能(样式模仿)
2019/12/10 Javascript
vue实现路由不变的情况下,刷新页面操作示例
2020/02/02 Javascript
JavaScript面向对象核心知识与概念归纳整理
2020/05/09 Javascript
[01:12:53]完美世界DOTA2联赛PWL S2 Forest vs SZ 第一场 11.25
2020/11/26 DOTA
Python进程间通信用法实例
2015/06/04 Python
Python的shutil模块中文件的复制操作函数详解
2016/07/05 Python
Python入门_学会创建并调用函数的方法
2017/05/16 Python
sublime python3 输入换行不结束的方法
2018/04/19 Python
python RabbitMQ 使用详细介绍(小结)
2018/11/08 Python
python3反转字符串的3种方法(小结)
2019/11/07 Python
TensorFlow Saver:保存和读取模型参数.ckpt实例
2020/02/10 Python
pycharm 2020 1.1的安装流程
2020/09/29 Python
CSS3制作皮卡丘动画壁纸的示例
2020/11/02 HTML / CSS
UGG英国官方网站:UGG UK
2018/02/08 全球购物
新闻记者实习自我鉴定
2013/09/19 职场文书
模具设计与制造专业推荐信
2014/02/16 职场文书
我的理想演讲稿
2014/04/30 职场文书
2015年度女工工作总结
2015/10/22 职场文书
CSS 实现Chrome标签栏的技巧
2021/08/04 HTML / CSS