layui中实现上传图片压缩
一、关于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
//生成canvas
var 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部分:
<form action="file/uploadDoc" enctype="multipart/form-data" method="post" id="form">
<input type="file" id="file" name="file" />
<input type="submit" value="上传" />
</form>
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 enctype="multipart/form-data" method="post" id="form">
<input type="file" id="file" name="file" />
<input type="button" value="上传" id="uploadBtn"/>
</form>
有些许的变化,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部分:
<button type="button" class="layui-btn" id="upImg">上传图片</button>
<div id="img_list">
</div>
<input type="button" id = "btnHide" class="none">
就是这么简单。为什么要再写一个隐藏的按钮,之后解释。
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中实现上传图片压缩的更多相关文章
- 微信小程序中如何上传图片
本篇文章给大家带来的内容是关于微信小程序中如何上传图片(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 一.wxml文件 <text>上传图片</text ...
- QEMU-KVM中的多线程压缩迁移技术
导读 目前的迁移技术,都是通过向QEMUFILE中直接写入裸内存数据来达到传送虚拟机的目的端,这种情况下,发送的数据量大,从而会导致更高的迁移时间(total time)和黑宕时间(downtime) ...
- C语言中的内存压缩技术
C语言中的内存压缩技术 前言 在整个研究生阶段我都在参与一个LTE协议栈实现的项目,在这个项目中,我们利用一个自己编写的有限状态机框架将协议栈中每一层实现为一个内核模块.我们知道,在编写内核代码时需要 ...
- ios怎样实现快速将显卡中数据读出压缩成视频在cocos2dx扩展开发中
如果解决ios怎样实现快速将显卡中数据读出压缩成视频在cocos2dx扩展开发中 手机平台性能是个关键问题. 压缩视频分成3个步骤: 读取显卡数据, 使用编码器压缩,保存文件. 使用libav 压缩的 ...
- HDFS中文件的压缩与解压
HDFS中文件的压缩与解压 文件的压缩有两大好处:1.可以减少存储文件所需要的磁盘空间:2.可以加速数据在网络和磁盘上的传输.尤其是在处理大数据时,这两大好处是相当重要的. 下面是一个使用gzip工具 ...
- layui中使用autocomplete.js
前言 在网站找了一大圈都是问题没有答案,记录记录谨防踩坑 layui版本:layui-v1.0.9_rls a(https://github.com/devbridge/jQuery-Autocomp ...
- Webpack 2 视频教程 015 - Webpack 2 中的文件压缩
原文发表于我的技术博客 这是我免费发布的高质量超清「Webpack 2 视频教程」. Webpack 作为目前前端开发必备的框架,Webpack 发布了 2.0 版本,此视频就是基于 2.0 的版本讲 ...
- Linux(常用命令) 中常用的压缩丶解压缩格式命令和参数详解
Linux中常用的压缩格式后缀名有:①.zip ②.gz ③.bz2 ④.tar.gz ⑤.tar.bz2 ①.zip后缀名格式 1.压缩 语法: ①zip 压缩文件名 源文件 (压缩文件) ...
- layer过去的时间不能选择,只能选择未来的时间 LayUI中的时间日期控件,设置时间范围,
默认Layui中的时间控件显示如下: 我当时系统时间是2018-06-07, 我需要做的是2018-06-07之后过去的时间不能选择 <p><span>时间范围:</sp ...
随机推荐
- 通过文件对照工具Merge数据库
项目分成线下开发版.线上測试版.线上生产版,因此相应有三个数据库. 对于一些静态数据.经常须要同步.改动了线下的开发版本号,同一时候也须要更新线上的測试版和线上生产版数据库,有时候线上的一些数据库改动 ...
- 0409-服务注册与发现-Eurek Ribbon Feign常见问题及解决
一.Eureka 1.1.Eureka Environment的配置: eureka.environment: 字符串 参考文档: https://github.com/Netflix/eureka/ ...
- Mycat教程---数据库的分库分表
mycat介绍 介绍在官方网站上有比较详细的介绍,在这里复制粘贴没什么意思,大家到官网上看 官网链接 前置条件 本教程是在window环境下运行的,实际生产推荐在Linux上运行. 必备条件(自行安装 ...
- git分支更新代码命令
第一步: 查看状态 git status 第二步: 全部添加 git add --all 第三步: 再次查看状态 git status 第四步: 提交 git commit -m '备 ...
- LeetCode:组合总数III【216】
LeetCode:组合总数III[216] 题目描述 找出所有相加之和为 n 的 k 个数的组合.组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字. 说明: 所有数字都是正整数. ...
- 左连接、右连接、内连接和where
首先可以看下w3school写的关于join的介绍: http://www.w3school.com.cn/sql/sql_join.asp on是关联条件,where是筛选条件 数据库在通过连接两张 ...
- EasyUI:所有的图标
EasyUI:所有的图标 所有的图标在 jquery-easyui-1.2.6/themes/icons 目录下: jquery-easyui-1.2.6/themes/icon.css .icon- ...
- sem学习
关键字的选取搜索引擎营销的关键字选取是非常重要的一步,合适的关键字可以为企业带来可观的咨询量.关键字一般分4种,品牌词,产品词,行业词,竞品词,对于这四类词不同的推广策略有着不同的侧重点,根据市场情况 ...
- 初入Spring-boot(一)
一.利用eclipse快速创建Spring-boot项目 1.首先去http://start.spring.io网站,勾选所需要的starter,如图: 选择完之后下载该文件,打开后发现是一个正常的m ...
- mysql——jdbc驱动下载&连接mysql例子
mysql-connector-java-5.1.46.zip[解压后里面jar文件就是所需要的] https://dev.mysql.com/get/Downloads/Connector-J/my ...