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

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

因为使用的是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多图片压缩上传内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2020-06-22

javascript中的Base64、UTF8编码与解码详解

Base64编码说明 Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式. 如果剩下的字符不足3个字节,则用0填充,输出字符使用'=',因此编码后输出的文本末尾可能会出现1或2个'='. base64编码库:(已验证可用) 复制代码 代码如下: var base64 = (function(){     var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn

js对图片base64编码字符串进行解码并输出图像示例

复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv=&qu

JS 实现Base64编码与解码实例详解

Js实现Base64编码与解码 Base64其实是一种简单的置换加密方式,但是BASE64的用处往往并不是为了防止信息泄露,而且为了方便传输,进过BASE64编码后的信息会比原始信息长,大概是4/3倍. Base64是一种基于64个可打印字符来表示二进制数据的表示方法.由于2的6次方等于64,所以每6个比特为一个单元,对应某个可打印字符. Base64常用于在通常处理文本数据的场合,表示.传输.存储一些二进制数据.包括MIME的email,email via MIME, 在XML中存储复杂数据.

JavaScript实现Base64编码转换

简介 Base64是一种基于64个可打印字符来表示二进制数据的表示方法.由于2的6次方等于64,所以每6个比特为一个单元,对应某个可打印字符.三个字节有24个比特,对应于4个Base64单元,即3个字节需要用4个可打印字符来表示.它可用来作为电子邮件的传输编码.在Base64中的可打印字符包括字母A-Z.a-z.数字0-9,这样共有62个字符,此外的两个可打印符号在不同的系统中而不同,一般为+和/. 转换原理 Base64的直接数据源是二进制序列(Binary Sequence).当然,你也可以

js 显示base64编码的二进制流网页图片

Data URI scheme. Data URI scheme是在RFC2397中定义的,目的是将一些小的数据,直接嵌入到网页中,从而不用再从外部文件载入.比如上面那串字符,其实是一张小图片,将这些字符复制黏贴到火狐的地址栏中并转到,就能看到它了,一张2*2的白色gif图片. 在上面的Data URI中,data表示取得数据的协定名称,image/gif是数据类型名称,base64 是数据的编码方法,逗号后面就是这个image/gif文件base64编码后的数据. 目前,Data URI sc

weui框架实现上传、预览和删除图片功能代码

jQuery WeUI 是专为微信公众账号开发而设计的一个简洁而强大的UI库,包含全部WeUI官方的CSS组件,并且额外提供了大量的拓展组件,丰富的组件库可以极大减少前端开发时间. jQuery WeUI 的最大特点是它只提供UI组件,并不会对项目所使用的框架和其他库有任何的限制,几乎可以在任何环境下使用.无论你的项目是基于jQuery,还是 React, Angular, Vue, 你都会发现 jQuery WeUI 能非常方便的和他们结合使用.既是你的项目是一个有很悠久历史的老项目,也几乎可

HTML5 JS压缩图片并获取图片BASE64编码上传

本文实例为大家分享了HTML5 JS压缩图片,并获取图片BASE64编码上传的方法,供大家参考,具体内容如下 基本过程 1) 调用 FileReader 的 reader.readAsDataURL(img); 方法, 在其onload事件中, 将用户选择的图片读入 Image对象. 2) 在image对象的 onload 事件中, 通过 canvas 的 canvas.getContext('2d') 的 drawImage 方法, 将Image 改变大小绘制到canvas上. 3) 通过 c

JS移动端/H5同时选择多张图片上传并使用canvas压缩图片

最近在做一个H5的项目,里边涉及到拍照上传图片的功能以及识别图片的功能,这里对识别图片的功能不做赘述,不属本文范畴.我在做完并上线项目后,同事跟我提了一个要求是可不可以同时选择多张图片上传,我做的时候的想法是如果给file表单加了 multiple 属性就没有办法调用手机的摄像头拍照了,如果不加,就无法同时选择多张图片,于是我就照实跟同事说了这个情况.但回头一想,单张图片可以上传,那多张图片呢?于是就有了本文的内容. HTML5定义了 FileReader 作为文件 API 的重要成员用于读取文

python将图片文件转换成base64编码的方法

本文实例讲述了python将图片文件转换成base64编码的方法.分享给大家供大家参考.具体实现方法如下: import base64 f=open(r'c:\jb51.gif','rb') #二进制方式打开图文件 ls_f=base64.b64encode(f.read()) #读取文件内容,转换为base64编码 f.close() 调用方法如下: 复制代码 代码如下: <img src="R0lGODlh1wBOAPcAAAAAAP///7a4u+jq7bG1ucrN0N7g4tLU

Struts2中图片以base64方式上传至数据库

1.页面 这里输入代码 <div> <span id="uploadImg" style="margin:50px;background-color:#ddd;display:inline-block;height:130px;width:200px;"> <span style="color:#bbb;font-weight:600;border:2px #ccc dashed;font-size:20px;text-ali

教你3分钟利用原生js实现有进度监听的文件上传预览组件

前言 本文主要介绍如何使用原生js,通过面向对象的方式实现一个文件上传预览的组件,该组件利用FileReader来实现文件在前端的解析,预览,读取进度等功能,并对外暴露相应api来实现用户自定义的需求,比如文件上传,进度监听,自定义样式,读取成功回调等. 组件设计架构如下: 涉及的核心知识点如下: 闭包:减少变量污染,缩短变量查找范围 自执行函数 file API:对文件进行读取,解析,监控文件事件 DocumentFragment API:主要用来优化dom操作 minix :用来实现对象混合

javascript实现获取指定精度的上传文件的大小简单实例

js实现获取指定精度的上传文件的大小,主要采用html和JavaScript,用浏览器运行下述代码,按照操作:选择文件->获得文件大小的顺序,即可. 源码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>获得文件大小</title> </head> <body> <f

js和jquery如何获取图片真实的宽度和高度

1.什么时候需要获取图片真实的宽度和高度 在做pc网页的时候,有时候会考虑按照插入的图片的尺寸来判断图片是横图还是竖图.然后判断过后给予不同的展示方式! 另外一种就是在手机页面上,在新闻页插入的图片往往都是按照图片的原尺寸来展示,如果手机屏幕太小,太大的图就会超出去!这时候有两种解决办法 1)给所有的图片加上这样的样式 1 复制代码 代码如下: .news img{margin:5px auto; display:block;width:100%; height:auto;} 但是这种方式有另外

解决.net项目中上传的图片或者文件太大无法上传问题

最近做项目的时候  用户提出要上传大图片  一张图片有可能十几兆  本来用的第三方的上传控件  有限制图片上传大小的设置 以前设置的是2M  按照用户的要求  以为直接将限制图片上传大小的设置改下就可以了  但是当上传大图片的时 总是异常: 错误消息:超过了最大请求长度 解决方案: 错误原因:asp.net默认最大上传文件大小为4M,运行超时时间为90S. 修改web.config中配置 <configuration> <system.web> <httpRuntime us

Android应用中拍照后获取照片路径并上传的实例分享

Activity 中的代码,我只贴出重要的事件部分代码 public void doPhoto(View view) { destoryBimap(); String state = Environment.getExternalStorageState(); if (state.equals(Environment.MEDIA_MOUNTED)) { Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); s

node.js实现带进度条的多文件上传

用node.js实现多文件上传并携带进度条的demo,供大家参考,具体内容如下 这个独立封装的需求来自一个朋友公司,他说需要写一个带进度条动画的批量上传文件的组件,结果他们后端跟他说不能多文件上传,我一听就很尴尬了,怎么可能不能多文件呢哈哈,后来我只是告诉他进度条的实现方式,在过了2天后我一直对此事耿耿于怀,所以干脆自己动手用node写了一个多文件上传的demo,并记录下来. 前端: http请求为自己封装的一个原生请求函数,一切以原生代码为主: 后端(nodeJs): express + mu