JS中图片压缩的方法小结


Posted in Javascript onNovember 14, 2017

首先想一想我们有哪些需求?大多时候我们需要将一个File对象压缩之后再变为File对象传入到远程图片服务器;有时候我们也需要将一个base64字符串压缩之后再变为base64字符串传入到远程数据库;有时候后它还有可能是一块canvas画布,或者是一个Image对象,或者直接就是一个图片的url地址,我们需要将它们压缩上传到远程;面对这么多的需求,王二索性画了一张图:

JS中图片压缩的方法小结

Alt text

二、解决办法

如上图所示,王二一共写了七个方法,基本覆盖了JS中大部分文件类型的转换与压缩,其中:

1、 urltoImage(url,fn) 会通过一个url加载所需要的图片对象,其中 url 参数传入图片的 url , fn 为回调方法,包含一个Image对象的参数,代码如下:

function urltoImage (url,fn){
  var img = new Image();
  img.src = url;
  img.onload = function(){
    fn(img);
  }
};

2、 imagetoCanvas(image) 会将一个 Image 对象转变为一个 Canvas 类型对象,其中 image 参数传入一个Image对象,代码如下:

function imagetoCanvas(image){
  var cvs = document.createElement("canvas");
  var ctx = cvs.getContext('2d');
  cvs.width = image.width;
  cvs.height = image.height;
  ctx.drawImage(image, 0, 0, cvs.width, cvs.height);
  return cvs ;
};

3、 canvasResizetoFile(canvas,quality,fn) 会将一个 Canvas 对象压缩转变为一个 Blob 类型对象;其中 canvas 参数传入一个 Canvas 对象; quality 参数传入一个0-1的 number 类型,表示图片压缩质量; fn 为回调方法,包含一个 Blob 对象的参数;代码如下:

function canvasResizetoFile(canvas,quality,fn){
  canvas.toBlob(function(blob) {
    fn(blob);
  },'image/jpeg',quality);
};

这里的 Blob 对象表示不可变的类似文件对象的原始数据。 Blob 表示不一定是 JavaScript 原生形式的数据。 File 接口基于 Blob ,继承了 Blob 的功能并将其扩展使其支持用户系统上的文件。我们可以把它当做File类型对待,其他更具体的用法可以参考MDN文档

4、 canvasResizetoDataURL(canvas,quality) 会将一个 Canvas 对象压缩转变为一个 dataURL 字符串,其中 canvas 参数传入一个 Canvas 对象; quality 参数传入一个0-1的 number 类型,表示图片压缩质量;代码如下:

methods.canvasResizetoDataURL = function(canvas,quality){
  return canvas.toDataURL('image/jpeg',quality);
};

其中的 toDataURL API可以参考MDN文档

5、 filetoDataURL(file,fn) 会将 File ( Blob )类型文件转变为 dataURL 字符串,其中 file 参数传入一个 File ( Blob )类型文件; fn 为回调方法,包含一个 dataURL 字符串的参数;代码如下:

function filetoDataURL(file,fn){
  var reader = new FileReader();
  reader.onloadend = function(e){
    fn(e.target.result);
  };
  reader.readAsDataURL(file);
};

6、 dataURLtoImage(dataurl,fn) 会将一串 dataURL 字符串转变为 Image 类型文件,其中 dataurl 参数传入一个 dataURL 字符串, fn 为回调方法,包含一个 Image 类型文件的参数,代码如下:

function dataURLtoImage(dataurl,fn){
  var img = new Image();
  img.onload = function() {
    fn(img);
  };
  img.src = dataurl;
};

7、 dataURLtoFile(dataurl) 会将一串 dataURL 字符串转变为 Blob 类型对象,其中 dataurl 参数传入一个 dataURL 字符串,代码如下:

function dataURLtoFile(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});
};

三、进一步封装

对于常用的将一个 File 对象压缩之后再变为 File 对象,我们可以将上面的方法再封装一下,参考如下代码:

function fileResizetoFile(file,quality,fn){
  filetoDataURL (file,function(dataurl){
    dataURLtoImage(dataurl,function(image){
      canvasResizetoFile(imagetoCanvas(image),quality,fn);
    })
  })
}

其中, file 参数传入一个 File ( Blob )类型文件; quality 参数传入一个 0-1 的 number 类型,表示图片压缩质量; fn 为回调方法,包含一个 Blob 类型文件的参数。

它使用起来就像下面这样:

var file = document.getElementById('demo').files[0];
fileResizetoFile(file,0.6,function(res){
  console.log(res);
  //拿到res,做出你要上传的操作;
})

这样的话,图片压缩上传就能轻松地搞定了,以上的8个方法我已经封装好放到 github 上了,喜欢的话可以使劲的star哈。

参考文档:

MDN

ps:下面看下JS等比压缩图片的办法

function proDownImage(path,imgObj) { // 等比压缩图片工具 
  //var proMaxHeight = 185; 
  var proMaxHeight=300; 
  var proMaxWidth = 175; 
  var size = new Object();  
  var image = new Image();  
  image.src = path;  
  image.attachEvent("onreadystatechange", 
  function() { // 当加载状态改变时执行此方法,因为img的加载有延迟 
    if (image.readyState == "complete") { // 当加载状态为完全结束时进入 
      if (image.width > 0 && image.height > 0) { 
        var ww = proMaxWidth / image.width; 
        var hh = proMaxHeight / image.height;  
        var rate = (ww < hh) ? ww: hh; 
        if (rate <= 1) {  
          alert("imgage width*rate is:" + image.width * rate); 
          size.width = image.width * rate; 
          size.height = image.height * rate; 
        } else { 
          alert("imgage width is:" + image.width); 
          size.width = image.width;
 
          size.height = image.height;
  
        }  
      } 
    } 
    imgObj.attr("width",size.width); 
    imgObj.attr("height",size.height); 
  }); 
}

总结

以上所述是小编给大家介绍的JS中图片压缩的方法小结,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
用javascript getComputedStyle获取和设置style的原理
Oct 10 Javascript
passwordStrength 基于jquery的密码强度检测代码使用介绍
Oct 08 Javascript
你必须知道的Javascript知识点之&quot;this指针&quot;的应用
Apr 23 Javascript
捕获和分析JavaScript Error的方法
Mar 25 Javascript
JavaScript调用传递变量参数的相关问题及解决办法
Nov 01 Javascript
浅谈javascript的call()、apply()、bind()的用法
Feb 21 Javascript
深入解析AngularJS框架中$scope的作用与生命周期
Mar 05 Javascript
AngularJS基础 ng-cloak 指令简单示例
Aug 01 Javascript
Vue.js每天必学之内部响应式原理探究
Sep 07 Javascript
关于Node.js的events.EventEmitter用法介绍
Apr 01 Javascript
Angular2实现组件交互的方法分析
Dec 19 Javascript
ES2020系列之空值合并运算符 '??'
Jul 22 Javascript
前端html中jQuery实现对文本的搜索功能并把搜索相关内容显示出来
Nov 14 #jQuery
Node.js使用Express.Router的方法
Nov 14 #Javascript
js精确的加减乘除实例
Nov 14 #Javascript
JavaScript插件Tab选项卡效果
Nov 14 #Javascript
vue中如何创建多个ueditor实例教程
Nov 14 #Javascript
基于 Vue 实现一个酷炫的 menu插件
Nov 14 #Javascript
Node之简单的前后端交互(实例讲解)
Nov 14 #Javascript
You might like
PHP获取ip对应地区和使用网络类型的方法
2015/03/11 PHP
php使用Jpgraph绘制简单X-Y坐标图的方法
2015/06/10 PHP
YII2 实现多语言配置的方法分享
2017/01/11 PHP
JavaScript replace(rgExp,fn)正则替换的用法
2010/03/04 Javascript
Javascript面向对象编程(三) 非构造函数的继承
2011/08/28 Javascript
JavaScript中使用typeof运算符需要注意的几个坑
2014/11/08 Javascript
浅析Node.js的Stream模块中的Readable对象
2015/07/29 Javascript
javascript每日必学之多态
2016/02/23 Javascript
模板视图和AngularJS之间冲突的解决方法
2016/11/22 Javascript
js实现移动端编辑添加地址【模仿京东】
2017/04/28 Javascript
结合mint-ui移动端下拉加载实践方法总结
2017/11/08 Javascript
用vue快速开发app的脚手架工具
2018/06/11 Javascript
jQuery实现checkbox全选功能完整实例
2018/07/12 jQuery
浅谈vue后台管理系统权限控制思考与实践
2018/12/19 Javascript
js实现菜单跳转效果
2020/12/11 Javascript
vue穿梭框实现上下移动
2021/01/29 Vue.js
[01:05:40]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS DT第三场
2014/05/24 DOTA
Python实现给文件添加内容及得到文件信息的方法
2015/05/28 Python
Python 模拟员工信息数据库操作的实例
2017/10/23 Python
解决nohup重定向python输出到文件不成功的问题
2018/05/11 Python
python3.6.3安装图文教程 TensorFlow安装配置方法
2020/06/24 Python
pandas DataFrame索引行列的实现
2019/06/04 Python
python实现植物大战僵尸游戏实例代码
2019/06/10 Python
解决python中导入win32com.client出错的问题
2019/07/26 Python
python线程定时器Timer实现原理解析
2019/11/30 Python
python中sympy库求常微分方程的用法
2020/04/28 Python
Python新建项目自动添加介绍和utf-8编码的方法
2020/12/26 Python
python 逆向爬虫正确调用 JAR 加密逻辑
2021/01/12 Python
Python学习之time模块的基本使用
2021/01/17 Python
三只松鼠官方旗舰店:全网坚果销售第1
2017/11/25 全球购物
保加利亚运动鞋购物网站:SneakerStudio.bg
2020/12/23 全球购物
计算机大学生的自我评价
2013/10/15 职场文书
公务员年总结的自我评价
2013/10/25 职场文书
报纸媒体创意广告词
2014/03/17 职场文书
董事长助理工作职责
2014/06/08 职场文书
解决hive中导入text文件遇到的坑
2021/04/07 Python