欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

图片转换js:img对象,file对象,base64,canvas对象,以及图片压缩方式讲解

程序员文章站 2022-06-13 18:53:18
首先想一想我们有哪些需求?大多时候我们需要将一个file对象压缩之后再变为file对象传入到远程图片服务器;有时候我们也需要将一个base64字符串压缩之后再变为base64字符串传入到远程;有时候...

首先想一想我们有哪些需求?大多时候我们需要将一个file对象压缩之后再变为file对象传入到远程图片服务器;有时候我们也需要将一个base64字符串压缩之后再变为base64字符串传入到远程;有时候后它还有可能是一块canvas画布,或者是一个image对象,或者直接就是一个图片的url地址,我们需要将它们压缩上传到远程;

二、解决办法

七个方法,基本覆盖了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 ;
};
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,做出你要上传的操作;
})

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