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 checkbox(复选框) 使用集锦
Apr 28 Javascript
javascript 一些用法小结
Sep 11 Javascript
jQuery实现鼠标划过修改样式的方法
Apr 14 Javascript
jQuery的层级查找方式分析
Jun 16 Javascript
BootStrap与Select2使用小结
Feb 17 Javascript
原生JS实现循环Nodelist Dom列表的4种方式示例
Feb 11 Javascript
JavaScript闭包与作用域链实例分析
Jan 21 Javascript
JS中的一些常用的函数式编程术语
Jun 15 Javascript
js 数组当前行添加数据方法详解
Jul 28 Javascript
elementui实现预览图片组件二次封装
Dec 29 Javascript
vue+element UI实现树形表格
Dec 29 Vue.js
JavaScript设计模式之原型模式详情
Jun 21 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 数组教程 定义数组
2009/10/23 PHP
PHP __autoload()方法真的影响性能吗?
2012/03/30 PHP
php 解决旧系统 查出所有数据分页的类
2012/08/27 PHP
PHP使用ODBC连接数据库的方法
2015/07/18 PHP
PHP实现抓取迅雷VIP账号的方法
2015/07/30 PHP
Javascript Global对象
2009/08/13 Javascript
非常有用的40款jQuery 插件推荐(系列二)
2011/12/25 Javascript
Knockout visible绑定使用方法
2013/11/15 Javascript
Node.js实现在目录中查找某个字符串及所在文件
2014/09/03 Javascript
鼠标经过子元素触发mouseout,mouseover事件的解决方案
2015/07/26 Javascript
jQuery+CSS3+Html5实现弹出层效果实例代码(附源码下载)
2016/05/16 Javascript
JS事件添加和移出的兼容写法示例
2016/06/20 Javascript
基于JS实现回到页面顶部的五种写法(从实现到增强)
2016/09/03 Javascript
Bootstrap图片轮播组件Carousel使用方法详解
2016/10/20 Javascript
jquery.uploadView 实现图片预览上传功能
2017/08/10 jQuery
Vue侧滑菜单组件——DrawerLayout
2017/12/18 Javascript
Vue中v-for的数据分组实例
2018/03/07 Javascript
JS简单获取并修改input文本框内容的方法示例
2018/04/08 Javascript
vue watch深度监听对象实现数据联动效果
2018/08/16 Javascript
vue3.0 CLI - 1 - npm 安装与初始化的入门教程
2018/09/14 Javascript
微信小程序的线程架构【推荐】
2019/05/14 Javascript
Vue.js项目实战之多语种网站的功能实现(租车)
2019/08/07 Javascript
跟老齐学Python之从格式化表达式到方法
2014/09/28 Python
python使用urllib2实现发送带cookie的请求
2015/04/28 Python
深入理解python中的atexit模块
2017/03/07 Python
python列表返回重复数据的下标
2020/02/10 Python
解决python ThreadPoolExecutor 线程池中的异常捕获问题
2020/04/08 Python
Python稀疏矩阵及参数保存代码实现
2020/04/18 Python
python3中celery异步框架简单使用+守护进程方式启动
2021/01/20 Python
利用Storage Event实现页面间通信的示例代码
2018/07/26 HTML / CSS
英国在线房屋中介网站:Yopa
2018/01/09 全球购物
ECCO俄罗斯官网:北欧丹麦鞋履及皮具品牌
2020/06/26 全球购物
南京导游词
2015/02/03 职场文书
2015年社区重阳节活动总结
2015/07/30 职场文书
pytorch通过训练结果的复现设置随机种子
2021/06/01 Python
html网页引入svg图片的4种方式
2022/08/05 HTML / CSS