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 相关文章推荐
asp.net和asp下ACCESS的参数化查询
Jun 11 Javascript
JavaScript 动态创建VML的方法
Oct 14 Javascript
window.open关于浏览器拦截问题分析及解决方法
Feb 05 Javascript
中止javascript执行的方法
Feb 14 Javascript
jQuery实现的图片分组切换焦点图插件
Jan 06 Javascript
jQuery实现预加载图片的方法
Mar 17 Javascript
微信小程序 MD5加密登录密码详解及实例代码
Jan 12 Javascript
node vue项目开发之前后端分离实战记录
Dec 13 Javascript
Javascript网页抢红包外挂实现分享
Jan 11 Javascript
JavaScript树的深度优先遍历和广度优先遍历算法示例
Jul 30 Javascript
js new Date()实例测试
Oct 31 Javascript
用JS实现飞机大战小游戏
Jun 09 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 array_intersect()函数使用代码
2009/01/14 PHP
解析PHP工厂模式的好处
2013/06/18 PHP
搭建Vim为自定义的PHP开发工具的一些技巧
2015/12/11 PHP
php版微信公众平台接口参数调试实现判断用户行为的方法
2016/09/23 PHP
YII分模块加载路由的实现方法
2018/10/01 PHP
PHP实现倒计时功能
2020/11/16 PHP
点击广告后才能获得下载地址
2006/10/26 Javascript
javascript基本语法分析说明
2008/06/15 Javascript
js window.onload 加载多个函数的方法
2009/11/02 Javascript
Prototype源码浅析 Enumerable部分(二)
2012/01/18 Javascript
jquery实现点击查看更多内容控制段落文字展开折叠效果
2015/08/06 Javascript
简单谈谈Javascript中类型的判断
2015/10/19 Javascript
javascript实现对表格元素进行排序操作
2015/11/18 Javascript
Vue2.0中三种常用传值方式(父传子、子传父、非父子组件传值)
2018/08/16 Javascript
详解javascript appendChild()的完整功能
2018/08/18 Javascript
js获取form表单中name属性的值
2019/02/27 Javascript
Node.JS枚举统计当前文件夹和子目录下所有代码文件行数
2019/08/23 Javascript
JavaScript arguments.callee作用及替换方案详解
2020/09/02 Javascript
[43:35]TI4 循环赛第二日Liquid vs Fnatic
2014/07/11 DOTA
python连接池实现示例程序
2013/11/26 Python
django 删除数据库表后重新同步的方法
2018/05/27 Python
Python程序打包工具py2exe和PyInstaller详解
2019/06/28 Python
python 哈希表实现简单python字典代码实例
2019/09/27 Python
对Pytorch 中的contiguous理解说明
2021/03/03 Python
AmazeUI 按钮交互的实现示例
2020/08/24 HTML / CSS
中间件的定义
2016/08/09 面试题
大一工商管理职业生涯规划:有梦最美,行动相随
2014/09/18 职场文书
教学改革问题查摆整改措施
2014/09/27 职场文书
党员个人剖析材料2014
2014/10/08 职场文书
2014年人事工作总结范文
2014/11/19 职场文书
爱牙日宣传活动总结
2015/02/05 职场文书
外贸英文求职信范文
2015/03/19 职场文书
导游词之安徽巢湖
2019/12/26 职场文书
Python包管理工具pip的15 个使用小技巧
2021/05/17 Python
Go 通过结构struct实现接口interface的问题
2021/10/05 Golang
如何避免mysql启动时错误及sock文件作用分析
2022/01/22 MySQL