JS多张图片压缩上传

  • 前言
  • 代码
  • 结尾

前言

最近在做的项目里有个关于多图片上传的,搞得我很久,查了很多资料,终于搞定,故此写一篇总结。

代码

前台我用的是jquery-1.8.3.min.js
html:

<div id="inputBox"><input type="file" title="请选择图片" id="file" multiple accept="image/png,image/jpg,image/gif,image/JPEG" onchange="addPhoto()"/>点击选择图片</div>
<div id="imgBox"></div>

js:
因为上传的图片要求不限制大小,就用了canvas压缩,再将base64转换为file放入文件流imgFile字段中,涉及到IE兼容问题就用了先将base64转换为blob再将blob转换为file。其中addNewContent方法实现预览效果,删除方法中的ajax会在下文提及。

var imgSrc = []; //图片路径
var imgFile = []; //文件流
var imgName = []; //图片名字
//压缩图片方法function compressImg(file){var src;var fileSize = parseFloat(parseInt(file['size'])/1024/1024).toFixed(2);var read = new FileReader();read.readAsDataURL(file);read.onload = function (e) {var img = new Image();img.src = e.target.result;img.onload = function(){//默认按比例压缩var w = this.width,h = this.height;//生成canvasvar canvas = document.createElement('canvas');var ctx = canvas.getContext('2d');var base64;// 创建属性节点canvas.setAttribute("width", w);canvas.setAttribute("height", h);ctx.drawImage(this, 0, 0, w, h);if(fileSize<1){console.log("1");//如果图片小于一兆 那么不执行压缩操作base64 = canvas.toDataURL(file['type'], 1);}else if(fileSize>1&&fileSize<2){console.log("0.5");//如果图片大于1M并且小于2M 那么压缩0.5base64 = canvas.toDataURL(file['type'], 0.5);}else{console.log("0.2");//如果图片超过2m 那么压缩0.2base64 = canvas.toDataURL(file['type'], 0.2);}// 回调函数返回file的值// callback(base64);var blob = dataURLtoBlob(base64);var files = blobToFile(blob, imgName);imgFile.push(files);};};};//将base64转换为blobfunction dataURLtoBlob(dataurl) {var arr = dataurl.split(','),mime = arr[0].match(/:(.*?);/)[1],bstr = atob(arr[1]),n = bstr.length,u8arr = new Uint8Array(n);while (n--) {u8arr[n] = bstr.charCodeAt(n);}return new Blob([u8arr], { type: mime });};//将blob转换为filefunction blobToFile(theBlob, fileName){theBlob.lastModifiedDate = new Date();theBlob.name = fileName;return theBlob;}function addPhoto() {var fileImg = $("#file")[0];var fileList = fileImg.files;for(var i = 0; i < fileList.length; i++) {var imgSrcI = getObjectURL(fileList[i]);imgName.push(fileList[i].name);imgSrc.push(imgSrcI);compressImg(fileList[i]);}addNewContent("#imgBox");}function addNewContent(obj) {$("#imgBox").html("");for(var a = 0; a < imgSrc.length; a++) {var oldBox = $(obj).html();$(obj).html(oldBox + '<div class="imgContainer"><img title=' + imgName[a] + ' alt=' + imgName[a] + ' src=' + imgSrc[a] + ' οnclick="imgDisplay(this)"><p οnclick="removeImg(this,' + a + ')" class="imgDelete">删除</p></div>');}}//删除function removeImg(obj, index) {console.log("imgSrc="+imgSrc.length);console.log("imgFile="+imgFile.length);console.log("imgName="+imgName.length);if(imgFile[index]==""){console.log("id="+imgName);var id = imgName[index];$.ajax({type: "post",url: "<%=request.getContextPath()%>/member/trade/doDelPicture.html",dataType: "json",data: {id: id},success: function (data) {if(data==0){console.log("删除成功!id:"+id);}}});}imgSrc.splice(index, 1);imgFile.splice(index, 1);imgName.splice(index, 1);var boxId = "#" + $(obj).parent('.imgContainer').parent().attr("id");addNewContent(boxId);}//限制图片个数function limitNum(num){if(!num){return true;}else if(imgFile.length>num){return false;}else{return true;}}//图片灯箱function imgDisplay(obj) {var src = $(obj).attr("src");var imgHtml = '<div style="width: 100%;height: 100vh;overflow: auto;background: rgba(0,0,0,0.5);text-align: center;position: fixed;top: 0;left: 0;z-index: 1000;"><img src=' + src + ' style="margin-top: 100px;width: 70%;margin-bottom: 100px;"/><p style="font-size: 50px;position: fixed;top: 30px;right: 30px;color: white;cursor: pointer;" οnclick="closePicture(this)">×</p></div>'$('body').append(imgHtml);}//关闭function closePicture(obj) {$(obj).parent("div").remove();}//图片预览路径function getObjectURL(file) {var url = null;if(window.createObjectURL != undefined) { // basicurl = window.createObjectURL(file);} else if(window.URL != undefined) { // mozilla(firefox)url = window.URL.createObjectURL(file);} else if(window.webkitURL != undefined) { // webkit or chromeurl = window.webkitURL.createObjectURL(file);}return url;}

在写上传前,先写初始时就有几张图片需要显示的情况。该情况需要将后台的图片在前台显示:

 @RequestMapping(value = "/member/trade/viewPhoto")@ResponseBodypublic void viewPhoto(HttpServletRequest request, HttpServletResponse response) throws IOException {String id = request.getParameter("id"); //前端传来的图片idbyte[] bookPicture = deliveryOrderService.findPicture(id); //获得bookPictureresponse.setContentType("image/jpeg");  //设置图片格式OutputStream out = response.getOutputStream(); //打开输出流if(bookPicture!=null){out.write(bookPicture);  //输出图片}out.flush();   //输出out.close();  //关闭输出}

前台初始化:
member/trade/getPhotoId为获取图片ID的ajax调用,这里就不多赘述。注意:这里获取到的只是图片的src路径,没有文件流,所以imgFile.push("");也因此删除图片时要判断图片是否是后台传来的图片if(imgFile[index]==""),如果是后台传来的图片就需要调用一下后台,将后台的图片一并删除

 $(function(){var id = $("[name=id]").val();var contextPath = $("[name=contextPath]").val();$.ajax({type: "post",url: "<%=request.getContextPath()%>/member/trade/getPhotoId.html",dataType: "json",data: {id: id},success: function (data) {data = eval(data);var msg = data.message;var basePath = data.result;$.each(msg, function (n, value) {console.log(n + '---' + value);var src = basePath+"member/trade/viewPhoto.html?id="+value;imgName.push(value);imgSrc.push(src);imgFile.push("");console.log(imgSrc);});addNewContent("#imgBox");}});})

也因此在做上传时只需要一起上传前台上传的图片,也就是imgFile文件流:注意文件上传的form便签<form id="addPickgoodsMain" method="post" enctype="multipart/form-data">

    function doSubmit(state){if(imgFile.length==0&&state==2 ){alert("请选择上传的文件!");return ;}if(!limitNum(100)){alert("超过图片上传限制");return;}if (!window.confirm('确定执行此操作吗?')) {return;}var formData = new FormData(document.getElementById('addPickgoodsMain'));var param=$("#addPickgoodsMain").serializeJson();param = JSON.stringify(param);console.log(param);formData.append("param",param);for(var i=0;i<imgFile.length;i++){formData.append("file1"+i+"[]",imgFile[i]);}$.ajax({type: "POST",url: "<%=request.getContextPath()%>/member/trade/orderEdit_signature.html",data: formData,async : false,contentType: false,processData: false,success: function(data) {if(data == '0') {alert("操作成功!")}else{alert("操作失败!")}}});}

后台接收用到CommonsMultipartResolver来获取请求中的文件流:

public void doAttchmentSave(HttpServletRequest request) throws IOException {CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());//判断 request 是否有文件上传,即多部分请求if (multipartResolver.isMultipart(request)) {//转换成多部分requestMultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;//取得request中的所有文件名Iterator<String> iter = multiRequest.getFileNames();while (iter.hasNext()) {//取得上传文件MultipartFile file = multiRequest.getFile(iter.next());if(file != null){//取得当前上传文件的文件名称String myFileName = file.getOriginalFilename();//如果名称不为空,说明该文件存在,否则说明该文件不存在if(!"".equals(myFileName.trim())){/**这里进行文件处理!!!*/}}}}}

结尾

到此,功能就结束了,第一次写博客,有什么不对的地方欢迎指出。希望对大家有用~~~~

利用JS来进行多张图片的压缩、预览、上传相关推荐

  1. uniapp利用uview2.0中的uploadFile组件实现多张图片的增删预览上传功能

    效果图 <template><view><view class="main-intro" style="background-color: ...

  2. 前端js实现上传图片大于2M时压缩,预览

    最近有个需求,用户在上传图片预览时,需要显示大小为2M以下,大于2M的需要压缩后上传,小于2M的原图显示 一.先说下限制图片大小的好处 直接上传特别占用带宽,上传速度慢,对程序考验以及影响用户的体验 ...

  3. php手机端多图预览上传,JS实现多图预览上传的实例代码

    这篇文章主要介绍了JS实现多张图片预览同步上传功能的相关资料,需要的朋友可以参考下 废话不多说了,直接给大家贴代码了,具体代码如下所示: /** * Created by liujing on 201 ...

  4. php仿微信上传图片压缩,PHP仿微信多图片预览上传实例代码

    生产图片区域,上传按钮#btn可替换自己想要的图片 plupload上传 var uploader = new plupload.Uploader({//创建实例的构造方法 runtimes: 'ht ...

  5. vue.js实现图片、视频文件压缩后再上传

    这里只展示图片上传代码 在这里插入代码片 ``` //html部分// 上传图片<div class="fileBox"><span class="fi ...

  6. js图片前端压缩多图上传(旋转其实已经好了只是手机端有问题要先压缩再旋转)...

    var filechooser = document.getElementById("choose");// 用于压缩图片的canvasvar canvas = document. ...

  7. js 导出pdf上传至oss_前端上传图片到oss,压缩图片后上传至oss(补充图片文件旋转90度问题)...

    上传图片如果过大,等待时间过长体验不好,于是使用js压缩图片再上传,无关图片清晰度. /** * 压缩图片 * @param file 图片文件 * @param callback 回调函数,压缩完要 ...

  8. vue.js — 安装Webpake创建一个完整的项目并上传至码云

    vue.js - 安装Webpake创建一个完整的项目并上传至码云 今天总结一下之前几天学习的一整套的创建项目方法: 前提条件:已安装node.js.npm/cnpm最新版本.vue-cli. VS ...

  9. 使用winrar压缩分卷(csdn上传大资源使用)

    使用winrar压缩分卷 csdn上传资源只有60M,上传大文件使用winrar的分卷压缩功能

最新文章

  1. 【 MATLAB 】gallery 中的 uniformdata
  2. 云和恩墨吴涵文:开源将加速成为中国未来发展基础软硬件技术的关键路径
  3. 《深入浅出DPDK》读书笔记(六):报文转发(run to completion、pipeline、精确匹配算法、最长前缀匹配LPM)
  4. 2014,都要好好的~
  5. linux文件恢复dbf,linux平台下数据文件被误删后,如何及时得知并进行恢复-dbf文件怎么打开...
  6. java ttf_使用iText从* .ttf文件创建字体
  7. Java中this、super的用法(2)
  8. Android开发之SharedPreferences
  9. Linux查看IP地址命令
  10. Js学习心得和思考方法
  11. ConneR and the A.R.C. Markland-N--- codeforces1293A
  12. USB虚拟串口(CDC)极限速度测试
  13. 【JavaWeb】火车票管理系统 (三)用户登录-03
  14. 机器学习技术:使用深度学习处理文本
  15. 【良心教程】保姆级Python爬虫入门教程(一)——爬虫之初见
  16. 互融云区块链溯源防伪系统开发,超高并发,全程追溯
  17. 工业类计算机主板维修,工控机电脑主板坏了如何维修
  18. 机器人来了!日本保险巨头启用AI替换30%理赔部员工
  19. 最佳平方逼近的Matlab
  20. 【STM32】内部温度传感器示例

热门文章

  1. Python 异步编程之——进程
  2. 【删除数组中重复的元素】
  3. 零基础学 Python爬虫(5):前置准备(四)数据库基础
  4. chmod 命令用法
  5. FLeiss Kappa系数和Kappa系数的Python实现
  6. temporal shift module(TSM)
  7. linux imx6 内核编译,iMX6UL---zlg M6G2C开发板内核编译记录
  8. mpf11_6_plotly update xaxis w dropdown menu_justify_Parabolic SAR_ADX smoothed TR/DM_Multicollineari
  9. 通过文件头判断图片格式
  10. 大学生创业能成功吗?——蒋涛 PK Leo实录(8)