前端 blob、url、base64、字符串的相互转换

135 阅读1分钟

最近做需求,要求上传图片后,点击图片打开一个新窗口呈现放大的效果。由于历史需求该图片转成了base64, 所以想着转成url利用window.open(url, '_blank')实现。最后在网上又搜索了一些文章,总结下常见的转换方式。(都是百度搜索的 如有侵权私聊删除)

  1. base64 -> blob (1)
export function b64toBlob(b64Data, contentType, sliceSize) {
  contentType = contentType || ''
  sliceSize = sliceSize || 512
  const byteCharacters = atob(b64Data.substring(b64Data.indexOf(',') + 1))
  const byteArrays = []
  for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
    const slice = byteCharacters.slice(offset, offset + sliceSize)
    const byteNumbers = new Array(slice.length)
    for (let i = 0; i < slice.length; i++) {
        byteNumbers[i] = slice.charCodeAt(i)
    }
    const byteArray = new Uint8Array(byteNumbers)
    byteArrays.push(byteArray)
  }
  const blob = new Blob(byteArrays, {type: contentType})
  return blob
}

(1)的简易版

function baseToBlob (b64) {
      const byteCharacters = atob(b64)
      const byteNumbers = new Array(byteCharacters.length)
      for (let i = 0; i < byteCharacters.length; i++) {
        byteNumbers[i] = byteCharacters.charCodeAt(i)
      }
      const byteArray = new Uint8Array(byteNumbers)
      const blob = new Blob([byteArray], { type: 'image/jpeg' })
      return blob
    }

(2)

function base64toBlob(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 });
}

(3)

fetch(`data:${type};base64,${base64}`).then(res => res.blob())
  1. blob -> base64
blobToBase64(blob) {
  return new Promise((resolve, reject) => {
    const fileReader = new FileReader();
    fileReader.onload = (e) => {
      resolve(e.target.result);
    };
    fileReader.readAsDataURL(blob);
    fileReader.onerror = () => {
      reject(new Error('blobToBase64 error'));
    };
  });
}
  1. blob -> url

(1)

 const blob = new Blob([图片二的进制流],{type:'image/jpeg'})
 let url = URL.createObjectURL(blob)  //创建URL

(2)

let url = URL.createObjectURL(this.files[0])
  1. url -> base64
   function urlToBase64(url) {
      return new Promise ((resolve,reject) => {
        let image = new Image();
        image.onload = function() {
          let canvas = document.createElement('canvas');
          canvas.width = this.naturalWidth;
          canvas.height = this.naturalHeight;
          canvas.getContext('2d').drawImage(image, 0, 0);
          let result = canvas.toDataURL('image/png')
          resolve(result);
        };
        // CORS 策略,会存在跨域问题https://stackoverflow.com/questions/20424279/canvas-todataurl-securityerror
        image.setAttribute("crossOrigin",'Anonymous');
        image.src = url;
        image.onerror = () => {
          reject(new Error('urlToBase64 error'));
      };
    }

  1. base64 -> url (也可采用上面的1和3)
function translateBase64ImgToBlob(base64,contentType){
     var arr = base64.split(',')  //去掉base64格式图片的头部
     var bstr = atob(arr[1])   //atob()方法将数据解码
     var leng = bstr.length
     var u8arr = new Uint8Array(leng)
     while(leng--){
        u8arr[leng] =  bstr.charCodeAt(leng) //返回指定位置的字符的 Unicode 编码
     }
     var blob = new Blob([u8arr],{type:contentType})
     var blobImg = {}
     blobImg.url = URL.createObjectURL(blob)  //创建URL
     blobImg.name = new Date().getTime() + '.png'
     return blobImg 	
}
  1. 字符串 -> base64 <-
let str = btoa(encodeURI("Dsgsg1234567890-=[];'m,,./文档"))
console.log(str)  //RHNnc2cxMjM0NTY3ODkwLT0lNUIlNUQ7J20sLC4vJUU2JTk2JTg3JUU2JUExJUEz
console.log(decodeURI(atob(str)))  //new_file2.html:80 Dsgsg1234567890-=[];'m,,./文档