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 相关文章推荐
js实现从数组里随机获取元素
Jan 12 Javascript
学习JavaScript设计模式(多态)
Nov 25 Javascript
详解使用vue-router进行页面切换时滚动条位置与滚动监听事件
Mar 08 Javascript
JS设置手机验证码60s等待实现代码
Jun 14 Javascript
Vuejs 页面的区域化与组件封装的实现
Sep 11 Javascript
AngualrJs清除定时器遇到的坑
Oct 13 Javascript
vue实现的上传图片到数据库并显示到页面功能示例
Mar 17 Javascript
JS实现中英文混合文字溢出友好截取功能
Aug 06 Javascript
解决angular2 获取到的数据无法实时更新的问题
Aug 31 Javascript
微信小程序--特定区域滚动到顶部时固定的方法
Apr 28 Javascript
浅谈Vue 自动化部署打包上线
Jun 14 Javascript
利用webpack理解CommonJS和ES Modules的差异区别
Jun 16 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
如何去掉文章里的 html 语法
2006/10/09 PHP
javascript中比较字符串是否相等的方法
2013/07/23 Javascript
跟我学Nodejs(二)--- Node.js事件模块
2014/05/21 NodeJs
JQuery中绑定事件(bind())和移除事件(unbind())
2015/02/27 Javascript
JQuery中DOM实现事件移除的方法
2015/06/13 Javascript
Jquery Easyui选项卡组件Tab使用详解(10)
2016/12/18 Javascript
JavaScript利用Date实现简单的倒计时实例
2017/01/12 Javascript
loading动画特效小结
2017/01/22 Javascript
jQuery插件zTree实现删除树节点的方法示例
2017/03/08 Javascript
详解用函数式编程对JavaScript进行断舍离
2017/09/18 Javascript
深入浅析Vue中的Prop
2018/06/10 Javascript
jquery 通过ajax请求获取后台数据显示在表格上的方法
2018/08/08 jQuery
Vue-cli3简单使用(图文步骤)
2019/04/30 Javascript
[01:17:12]职来职往完美电竞专场
2014/09/18 DOTA
Python中实现两个字典(dict)合并的方法
2014/09/23 Python
详解Python使用simplejson模块解析JSON的方法
2016/03/24 Python
深度定制Python的Flask框架开发环境的一些技巧总结
2016/07/12 Python
Django与JS交互的示例代码
2017/08/23 Python
详解supervisor使用教程
2017/11/21 Python
PyQt5每天必学之拖放事件
2020/08/27 Python
Python3.5以上版本lxml导入etree报错的解决方案
2019/06/26 Python
Python使用Numpy模块读取文件并绘制图片
2020/05/13 Python
通过实例解析python创建进程常用方法
2020/06/19 Python
CSS3实现红包抖动效果
2020/12/23 HTML / CSS
adidas官方旗舰店:德国运动用品制造商
2017/11/25 全球购物
在对linux系统分区进行格式化时需要对磁盘簇(或i节点密度)的大小进行选择,请说明选择的原则
2012/01/13 面试题
大学毕业感言一句话
2014/02/06 职场文书
信息服务专业毕业生求职信
2014/03/02 职场文书
夫妻忠诚协议书范本
2014/11/17 职场文书
2014小学数学教研组工作总结
2014/12/06 职场文书
优秀班集体事迹材料
2014/12/25 职场文书
法学专业求职信范文
2015/03/19 职场文书
物业项目经理岗位职责
2015/04/01 职场文书
公司团队口号霸气押韵
2015/12/24 职场文书
golang switch语句的灵活写法介绍
2021/05/06 Golang
HTML页面中使两个div并排显示的实现
2022/05/15 HTML / CSS