JS中图片压缩的方法小结

本文总结了JavaScript中处理图片压缩的多种方法,包括从URL加载图片、Image转Canvas、Canvas压缩为Blob和dataURL等,提供了7个核心函数,覆盖了常见的图片处理需求,并封装了一个方便的文件压缩函数。最后,作者分享了代码库的GitHub链接。

首先想一想我们有哪些需求?大多时候我们需要将一个File对象压缩之后再变为File对象传入到远程图片服务器;有时候我们也需要将一个base64字符串压缩之后再变为base64字符串传入到远程数据库;有时候后它还有可能是一块canvas画布,或者是一个Image对象,或者直接就是一个图片的url地址,我们需要将它们压缩上传到远程;面对这么多的需求,王二索性画了一张图:

Alt text

二、解决办法

如上图所示,王二一共写了七个方法,基本覆盖了JS中大部分文件类型的转换与压缩,其中:

1、 urltoImage(url,fn) 会通过一个url加载所需要的图片对象,其中 url 参数传入图片的 url , fn 为回调方法,包含一个Image对象的参数,代码如下:

?

1

2

3

4

5

6

7

function urltoImage (url,fn){

  var img = new Image();

  img.src = url;

  img.onload = function(){

    fn(img);

  }

};

2、 imagetoCanvas(image) 会将一个 Image 对象转变为一个 Canvas 类型对象,其中 image 参数传入一个Image对象,代码如下:

?

1

2

3

4

5

6

7

8

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 对象的参数;代码如下:

?

1

2

3

4

5

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 类型,表示图片压缩质量;代码如下:

?

1

2

3

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 字符串的参数;代码如下:

?

1

2

3

4

5

6

7

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 类型文件的参数,代码如下:

?

1

2

3

4

5

6

7

function dataURLtoImage(dataurl,fn){

  var img = new Image();

  img.onload = function() {

    fn(img);

  };

  img.src = dataurl;

};

7、 dataURLtoFile(dataurl) 会将一串 dataURL 字符串转变为 Blob 类型对象,其中 dataurl 参数传入一个 dataURL 字符串,代码如下:

?

1

2

3

4

5

6

7

8

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 对象,我们可以将上面的方法再封装一下,参考如下代码:

?

1

2

3

4

5

6

7

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 类型文件的参数。

它使用起来就像下面这样:

?

1

2

3

4

5

var file = document.getElementById('demo').files[0];

fileResizetoFile(file,0.6,function(res){

  console.log(res);

  //拿到res,做出你要上传的操作;

})

这样的话,图片压缩上传就能轻松地搞定了,以上的8个方法我已经封装好放到 github 上了,喜欢的话可以使劲的star哈。

参考文档:

MDN

ps:下面看下JS等比压缩图片的办法

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

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);

  });

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值