使用js在layui中实现上传图片压缩
前端  /  管理员 发布于 4年前   315
一、关于js上传图片压缩的方法,百度有很多种方法,这里我参考修改了一下
function photoCompress(file, w, objDiv) {var ready = new FileReader();/*开始读取指定的Blob对象或File对象中的内容. 当读取操作完成时,readyState属性的值会成为DONE,如果设置了onloadend事件处理程序,则调用之.同时,result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容.*/ready.readAsDataURL(file);ready.onload = function() {var re = this.result;canvasDataURL(re, w, objDiv);}};function canvasDataURL(path, obj, callback) {var img = new Image();img.src = path;img.onload = function() {var that = this;// 默认按比例压缩var w = that.width,h = that.height,scale = w / h;w = obj.width || w;h = obj.height || (w / scale);var quality = 0.5; // 默认图片质量为0.7//生成canvasvar canvas = document.createElement('canvas');var ctx = canvas.getContext('2d');// 创建属性节点var anw = document.createAttribute("width");anw.nodeValue = w;var anh = document.createAttribute("height");anh.nodeValue = h;canvas.setAttributeNode(anw);canvas.setAttributeNode(anh);ctx.drawImage(that, 0, 0, w, h);// 图像质量if(obj.quality && obj.quality <= 1 && obj.quality > 0) {quality = obj.quality;}// quality值越小,所绘制出的图像越模糊var base64 = canvas.toDataURL('image/jpeg', quality);// 回调函数返回base64的值callback(base64);}}function convertBase64UrlToBlob(urlData) {var arr = urlData.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});}
以上是压缩图片的方法,核心是将图片放入canvas内,再用canvas.toDataURL方法进行压缩,最后生成一个Blob对象。
注:因为牵扯到canvas,所以低版本浏览器应该是不支持的吧(有待考证)
二、图片压缩的方法有了,怎么使用呢?怎么上传到后台呢?往下看!
html部分:
js部分:
$("#file").change(function() {var formData = new formData("form");var file = this.files[0];photoCompress(file, {quality: 0.5,}, function(base64Codes) {var bl = convertBase64UrlToBlob(base64Codes);formData.set("file", bl, file.name);});});
当选择文件以后,使用photoCompress方法对上传的图片进行压缩,photoCompress方法的第二个参数还可以传入长宽等参数,具体可以看photoCompress这个方法,quality是用来设置压缩后图片质量的,越小质量越差,表现出来就是图片越模糊,但是相应的体积就越小。
最后使用formData.set(key,value,name)方法,将现有的name为file的表单元素的值改变。这个方法有三个参数,第一个是key值,也就是表单里对应的元素的name值(如果不存在会自行添加),第二个值是value值,第三个是选填的值,如果第二个值为blob对象或者file对象,则第三个值表示文件名。
当然,如果你不想用form表单提交,你也可以用ajax提交的方法:
html:
有些许的变化,form没有了action,上传的按钮type改为了button
js部分给按钮添加一个点击事件,其他也没有变化,不做过多赘述:
$("#uploadBtn").click(function () {var formData = new formData("form");$.ajax({type:"post",url:"",async:true,data:formData,success:function (data) {},error:function (e) {}});});
三、结合layui踩的一些坑,以及最终的解决方法。
先看html部分:
就是这么简单。为什么要再写一个隐藏的按钮,之后解释。
js部分:
layui.use('upload', function() {var upload = layui.upload;var uploadInst = upload.render({elem: '#upImg',url: '/upload/',auto: false,bindAction: "#btnHide",choose: function(obj) {var files = obj.pushFile();var index, file, indexArr = [];for(index in files) {indexArr.push(index);};var iaLen = indexArr.length;file = files[indexArr[iaLen - 1]];for(var i = 0; i < iaLen - 1; i++) {delete files[indexArr[i]];}try {if(file.size > 200 * 1024) {delete files[index];photoCompress(file, {quality: 0.5,}, function(base64Codes) {var bl = convertBase64UrlToBlob(base64Codes);obj.resetFile(index, bl, file.name);$("#btnHide").trigger("click");});} else {$("#btnHide").trigger("click");}} catch(e) {$("#btnHide").trigger("click");}},done: function(res) {//这里把后台返回的数据进行操作,展示上传完成的图片,具体数据格式参考layui的API},error: function() {}});});原理:在选择照片之后,获取文件,转换为blob对象,使用resetFile方法对文件列队里的文件进行重新设置,然后再触发上传事件。
踩的坑:
1、resetFile这个方法是layui 2.3.0 新增的,所以首先要确保layui的版本是最新的。
2、我把auto设置为false,点击btnHide时触发上传,我也试过自动上传,自动上传的话,这些操作的代码就要写在before方法中(具体看layui的API),然而我发现自动上传修改文件列队的方法总是在上传成功之后才调用,这就导致实际上传的图片其实没有压缩,至于为什么是这个执行顺序我隐约觉得是不是图片转码,放入canvas的时候耽误了……具体原因我不明白,所以我用手动上传,确认修改了文件列队,再手动触发上传。
3、关于文件列队,多次上传文件,文件列队也就是obj.pushFile()返回的是多个文件的对象,而且这些文件对象的key还是一串随机数……所以我的思路是上传一次,就用delete方法删除队列中已上传过的文件。至于为什么不直接全部清空,因为考虑到不需要压缩的情况,如果全部清空,不压缩,就没有执行resetFile方法,文件列队里就没有文件,会报错。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
您可能感兴趣的文章:
- layui 上传图片 返回图片地址的方法
- layui上传图片到服务器的非项目目录下的方法
123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..路人 在
php中使用hyperf框架调用讯飞星火大模型实现国内版chatgpt功能示例中评论 教程很详细,如果加个前端chatgpt对话页面就完美了..Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号