本文参考:https://zhuanlan.zhihu.com/p/339477329

一,base64概述

1,base64

Base64,顾名思义,就是包括小写字母a-z、大写字母A-Z、数字0-9、符号"+“、”/“一共64个字符的字符集,(另加一个“=”,实际是65个字符,至于为什么还会有一个“=”,这个后面再说)。任何符号都可以转换成这个字符集中的字符,这个转换过程就叫做base64编码。

2,base64编码原理

首先将字符串(图片等)转换成二进制序列,然后按每6个二进制位为一组,分成若干组,如果不足6位,则低位补0。每6位组成一个新的字节,高位补00,构成一个新的二进制序列,这样每8位数据表示之前的6位,且最高两位必为00,2^6=64,正好对应64个字符。最后根据base64索引表中的值找到对应的字符。

请添加图片描述
有字符串“abc", 我们要对其进行base64编码,最后结果会是什么呢?
在这里插入图片描述
字符串abc对应3个字节,一共24位,按6位为一组可分为4组,在每组的高位补上00,经过转换,abc 的 base64 编码是 YWJj, 由原来的3个字母变成了4个,所以base64会比原字符串更长。
那问题来了,假设原始字符串不够3个字节,只有一个字节或者两个字节怎么办?

以两个字节为例, 按照上面的转换逻辑,经过编码转换,第三个字节只有4位,需要在第三组前后都要加两个0,转换后的字符串是 YWI。 为了凑齐4个字节,还要在末尾补上一个"="号,最后得到的base64编码就是: “YWI=”
如果原始字符只有一个字节,原理是类似的,第二个字节除了前面补两个0,还要在后面补4个0,得到的字符串是YQ,剩下两个字节也用等号“=”来凑。所以a的base64编码就是 YQ==
总结一点就是只要原始字符串的长度不能被3整除,后面的位都会用0来补充。所以说base64的末尾有时有=有时==有时没有=号

3,base64在前端页面的使用

绝大多数现代浏览器都支持一种名为 Data URLs 的特性,允许使用 base64 对图片或其他文件的二进制数据进行编码,将其作为文本字符串嵌入网页中。
Data URLs 由四个部分组成:前缀(data:)、指示数据类型的 MIME 类型、如果非文本则为可选的 base64 标记、数据本身:

data:[<mediatype>][;base64],<data>

例如,我们常用的图片则是:

data:image/jpeg;base64,base64Value
<img alt="logo" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...">

二,blob概述

Blob(Binary Large Object)表示二进制类型的大对象。在数据库管理系统中,将二进制数据存储为一个单一个体的集合。

Blob 对象表示一个不可变、原始数据的类文件对象。Blob 表示的不一定是JavaScript原生格式的数据。File 接口基于Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。

Blob对象有两个属性:size 和 type。其中 size 属性用于表示数据的大小(以字节为单位),type 是 MIME 类型的字符串。

三,在js中生成base64

在js里生成base64的API有两个,一个是FileReader,一个是画布canvas。

1,使用canvas获取base64

// 这个image就是输入
// 除了new,也可以直接取页面上的标签
var image = new Image();

image.onload = function () {
   var w = image.width;
   var h = image.height;
   var canvas = document.createElement('canvas');
   var ctx = canvas.getContext("2d");
   canvas.width = w;
   canvas.height = h;
   ctx.drawImage(image, 0, 0, w, h);
   // 可以在这里添加水印或者合并图片什么的    
   ...
   // 把画布的内容转成base64,这个就是输出
   var base64 = canvas.toDataURL('image/jpeg');
   console.log(base64)
}
// 这个src可以是本地路径,服务器图片地址,也可以是上面fileReader的base64,当这里赋值后,上面的omload的函数会得到执行
image.src = "xxx.jpg";

2,使用FileReader获取base64

<input type="file" onchange="change(this.files[0])">
function change(file){
   var fr = new FileReader()
   fr.onload = function(e) { 
      // 这个就是base64
      console.log( e.target.result );
   }
   // 这个方法传参是一个Blob类型的格式
   fr.readAsDataURL(file)
}

四,利用blob和base64进行图片的压缩

base64的初衷是加工图片或者压缩图片,否则我们获取base64将毫无意义。

/* 压缩base64图片 */
function compress(
  base64, // 源图片
  rate, // 缩放比例
  callback, // 回调
  maxSize //最大尺寸
) {
  //处理缩放,转格式
  var _img = new Image();
  _img.src = base64;//这里赋值之后就会触发onload函数
  _img.onload = function () {
    var _canvas = document.createElement('canvas');
    var w = this.width / rate;
    var h = this.height / rate;
    _canvas.setAttribute('width', w);
    _canvas.setAttribute('height', h);
    _canvas.getContext('2d').drawImage(this, 0, 0, w, h);//this就是这个_img,在 这里画出缩小的图
    var base64 = _canvas.toDataURL('image/jpeg');//然后把缩小的图转化为base64了,实现了图片的压缩
    _canvas.toBlob(function (blob) {
      if (blob.size > maxSize) {
        //如果还大,继续压缩
        compress(base64, rate, callback);
      } else {
        callback(base64);
      }
    }, 'image/jpeg');
  };
}

它的原理是使用画布,先画出缩放指定比例的canvas图片,然后再转成base64。这样就实现了图片的压缩。
这里判断图片的大小,是通过_canvas.toBlob,然后利用blob的size属性实现的。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐