Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

图片的三种表现形式,url,base64,blob以及相互转化 #9

Open
heightzhang opened this issue Feb 13, 2019 · 4 comments
Open

Comments

@heightzhang
Copy link
Owner

heightzhang commented Feb 13, 2019

目前的转化流程图:

流程图

一、url 转 base64

url to base64的方法封装

// 利用canvas.toDataURL的API转化成base64

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);
        // result
        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('图片流异常'));
    };
}

你可以这样调用:

let imgUrL = `http://XXX.jpg`

const imgBase64 = this.getDataUri(imgUrL).then(res => {
  // 转化后的base64图片地址
  console.log('base64', res)
})

二、base64 转 blob

base64 to blob 的方法封装

// 原理: 利用URL.createObjectURL为blob对象创建临时的URL

base64ToBlob ({b64data = '', contentType = '', sliceSize = 512} = {}) {
    return new Promise((resolve, reject) => {
      // 使用 atob() 方法将数据解码
      let byteCharacters = atob(b64data);
      let byteArrays = [];
      for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
        let slice = byteCharacters.slice(offset, offset + sliceSize);
        let byteNumbers = [];
        for (let i = 0; i < slice.length; i++) {
            byteNumbers.push(slice.charCodeAt(i));
        }
        // 8 位无符号整数值的类型化数组。内容将初始化为 0。
        // 如果无法分配请求数目的字节,则将引发异常。
        byteArrays.push(new Uint8Array(byteNumbers));
      }
      let result = new Blob(byteArrays, {
        type: contentType
      })
      result = Object.assign(result,{
        // jartto: 这里一定要处理一下 URL.createObjectURL
        preview: URL.createObjectURL(result),
        name: `图片示例.png`
      });
      resolve(result)
    })
 }

你可以这样调用:

let base64 = base64.split(',')[1]

this.base64ToBlob({b64data: base64, contentType: 'image/png'}).then(res => {
    // 转后后的blob对象
    console.log('blob', res)
})

三、 blob 转 base64

blob to 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('文件流异常'));
      };
    });
}

你可以这样调用:

this.blobToBase64(blob).then(res => {
    // 转化后的base64
    console.log('base64', res)
})

后续有时间补充其他类型的转化方法...

我的原文链接(包含业务情景再现):传送门

ps:本文是在玩转图片流的优化,感谢原作者

@heightzhang heightzhang changed the title 图片的三种表现形式,url,base64,blob的相互转化 图片的三种表现形式,url,base64,blob以及相互转化 Feb 13, 2019
@kybetter
Copy link

太棒了

@miloshu
Copy link

miloshu commented Mar 9, 2019

base64 转 blob, 代码复制过去 eslint报错, 具体怎么使用?

@miloshu
Copy link

miloshu commented Mar 9, 2019

let base64 = base64.split(',')[1]
这段的base64是在哪里定义的?

@heightzhang
Copy link
Owner Author

base64 转 blob, 代码复制过去 eslint报错, 具体怎么使用?
eslint报错是eslint中你定义的代码规范问题,你可以在google上找到解决方法。

let base64 = base64.split(',')[1]
这段的base64是在哪里定义的?
这段的base64是指data:image/jpeg;base64,XXXX
这段代码的含义是将data:image/jpeg;base64,XXXX分割为两个数组,取值为XXXX(base64编码)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants