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 相关文章推荐
精解window.setTimeout()&amp;window.setInterval()使用方式与参数传递问题!
Nov 23 Javascript
JQuery之拖拽插件实现代码
Apr 14 Javascript
jQuery学习总结之元素的相对定位和选择器(持续更新)
Apr 26 Javascript
解析javascript系统错误:-1072896658的解决办法
Jul 08 Javascript
Express.JS使用详解
Jul 17 Javascript
13 款最热门的 jQuery 图像 360 度旋转插件推荐
Dec 09 Javascript
js实现点击切换TAB标签实例
Aug 21 Javascript
jquery实现最简单的滑动菜单效果代码
Sep 12 Javascript
JavaScript实现为事件句柄绑定监听函数的方法分析
Nov 14 Javascript
用图片替换checkbox原始样式并实现同样的功能
Nov 15 Javascript
jQuery实现input[type=file]多图预览上传删除等功能
Aug 02 jQuery
vue实现移动端返回顶部
Oct 12 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
深入apache配置文件httpd.conf的部分参数说明
2013/06/28 PHP
PHP连接Nginx服务器并解析Nginx日志的方法
2015/08/16 PHP
PHP共享内存用法实例分析
2016/02/12 PHP
总结PHP中初始化空数组的最佳方法
2019/02/13 PHP
浅谈javascript属性onresize
2015/04/20 Javascript
jquery实现左右滑动式轮播图
2017/03/02 Javascript
jquery版轮播图效果和extend扩展
2017/07/18 jQuery
react-router4 嵌套路由的使用方法
2017/07/24 Javascript
微信小程序踩坑记录之解决tabBar.list[3].selectedIconPath大小超过40kb
2018/07/04 Javascript
VUE+elementui面包屑实现动态路由详解
2019/11/04 Javascript
Vue 封装防刷新考试倒计时组件的实现
2020/06/05 Javascript
[02:07]TI9显影之尘系列 - Vici Gaming
2019/08/20 DOTA
在Django中创建URLconf相关的通用视图的方法
2015/07/20 Python
在windows系统中实现python3安装lxml
2016/03/23 Python
Python实现将数据框数据写入mongodb及mysql数据库的方法
2018/04/02 Python
pandas DataFrame实现几列数据合并成为新的一列方法
2018/06/08 Python
Pycharm更换python解释器的方法
2018/10/29 Python
配置 Pycharm 默认 Test runner 的图文教程
2018/11/30 Python
Django之模板层的实现代码
2019/09/09 Python
OpenCV+python实现膨胀和腐蚀的示例
2020/12/21 Python
Django项目在pycharm新建的步骤方法
2021/03/02 Python
Tripadvisor新西兰:阅读评论,比较价格和酒店预订
2018/02/10 全球购物
美国时尚大码女装购物网站:Avenue
2019/05/24 全球购物
物流专业求职计划书
2014/01/10 职场文书
护士思想汇报
2014/01/12 职场文书
幼儿园教师辞职信
2014/01/18 职场文书
企业承诺书怎么写
2014/05/24 职场文书
2014年保险公司工作总结
2014/11/22 职场文书
2014年人事行政工作总结
2014/12/03 职场文书
南湾猴岛导游词
2015/02/09 职场文书
2015年度个人工作总结报告
2015/10/24 职场文书
2016重阳节红领巾广播稿
2015/12/18 职场文书
MySQL中几种插入和批量语句实例详解
2021/09/14 MySQL
德劲DE1102数字调谐收音机机评
2022/04/07 无线电
为自由献出你的心脏!「进击的巨人展 FINAL」2022年6月在台开展
2022/04/13 日漫
Nginx如何配置多个服务域名解析共用80端口详解
2022/09/23 Servers