最近做需求,要求上传图片后,点击图片打开一个新窗口呈现放大的效果。由于历史需求该图片转成了base64, 所以想着转成url利用window.open(url, '_blank')实现。最后在网上又搜索了一些文章,总结下常见的转换方式。(都是百度搜索的 如有侵权私聊删除)
- 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())
- 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'));
};
});
}
- blob -> url
(1)
const blob = new Blob([图片二的进制流],{type:'image/jpeg'})
let url = URL.createObjectURL(blob) //创建URL
(2)
let url = URL.createObjectURL(this.files[0])
- 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'));
};
}
- 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
}
- 字符串 -> base64 <-
let str = btoa(encodeURI("Dsgsg1234567890-=[];'m,,./文档"))
console.log(str) //RHNnc2cxMjM0NTY3ODkwLT0lNUIlNUQ7J20sLC4vJUU2JTk2JTg3JUU2JUExJUEz
console.log(decodeURI(atob(str))) //new_file2.html:80 Dsgsg1234567890-=[];'m,,./文档