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 相关文章推荐
各种效果的jquery ui(接口)介绍
Sep 17 Javascript
JS保存、读取、换行、转Json报错处理方法
Jun 14 Javascript
js实现双击图片放大单击缩小的方法
Feb 17 Javascript
js实现touch移动触屏滑动事件
Apr 17 Javascript
jQuery中通过ajax的get()函数读取页面的方法
Feb 29 Javascript
jQuery的内容过滤选择器学习教程
Apr 18 Javascript
详解JavaScript中Hash Map映射结构的实现
May 21 Javascript
jQuery简单倒计时效果完整示例
Sep 20 Javascript
js实现带简单弹性运动的导航条
Feb 22 Javascript
jQuery实现的滑块滑动导航效果示例
Jun 04 jQuery
angular2/ionic2 实现搜索结果中的搜索关键字高亮的示例
Aug 17 Javascript
vuejs实现折叠面板展开收缩动画效果
Sep 06 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实现WEB动态网页静态
2006/10/09 PHP
CI框架中redis缓存相关操作文件示例代码
2016/05/17 PHP
PHP+Ajax 检测网络是否正常实例详解
2016/12/16 PHP
广告显示判断
2006/08/31 Javascript
Jquery中增加参数与Json转换代码
2009/11/20 Javascript
原生javascript实现图片轮播效果代码
2010/09/03 Javascript
javascript计算星座属相(十二生肖属相)示例代码
2014/01/09 Javascript
JavaScript中使用Callback控制流程介绍
2015/03/16 Javascript
CascadeView级联组件实现思路详解(分离思想和单链表)
2016/04/12 Javascript
微信支付 JS API支付接口详解
2016/07/11 Javascript
JavaScript页面实时显示当前时间实例代码
2016/10/23 Javascript
Bootstrap基本布局实现方法详解
2016/11/25 Javascript
bootstrap table操作技巧分享
2017/02/15 Javascript
angular.js + require.js构建模块化单页面应用的方法步骤
2017/07/19 Javascript
angularjs实现分页和搜索功能
2018/01/03 Javascript
详解给Vue2路由导航钩子和axios拦截器做个封装
2018/04/10 Javascript
vue addRoutes实现动态权限路由菜单的示例
2018/05/15 Javascript
详解element-ui动态限定的日期范围选择器代码片段
2020/07/03 Javascript
利用Python的Flask框架来构建一个简单的数字商品支付解决方案
2015/03/31 Python
Python入门之modf()方法的使用
2015/05/15 Python
django使用图片延时加载引起后台404错误
2017/04/18 Python
Python利用ElementTree模块处理XML的方法详解
2017/08/31 Python
Python实现监控Nginx配置文件的不同并发送邮件报警功能示例
2019/02/26 Python
利用python实现凯撒密码加解密功能
2020/03/31 Python
Python 日期时间datetime 加一天,减一天,加减一小时一分钟,加减一年
2020/04/16 Python
Python基于jieba, wordcloud库生成中文词云
2020/05/13 Python
解决Keyerror ''acc'' KeyError: ''val_acc''问题
2020/06/18 Python
python工具快速为音视频自动生成字幕(使用说明)
2021/01/27 Python
个人查摆剖析材料
2014/10/04 职场文书
技术入股合作协议书
2014/10/07 职场文书
幼儿园六一儿童节演讲稿
2015/03/19 职场文书
质量承诺书格式范文
2015/04/28 职场文书
2015年污水处理厂工作总结
2015/05/26 职场文书
公司费用报销管理制度
2015/08/04 职场文书
读《推着妈妈去旅行》有感1500字
2019/10/15 职场文书
Redis配置外网可访问(redis远程连接不上)的方法
2022/12/24 Redis