Blob与对象URL的创建

219 阅读2分钟

最近项目中遇到了一个需求,就是要把base64转成mapbox的图像源,添加到图层中。如果是img标签的话可以直接把base64放到src属性中渲染,但是在三维渲染框架mapbox中却无法直接把base64拿来用,需要用到对象URL,这里需要用Blob来做一次中转。

Blob对象在javascript编程文件处理中经常遇到,它表示binary large object,是JavaScript对不可修改二进制数据的封装类型。它实际上是File的超类,我们可以把它想象成File对象的片段或者整个File对象。

我们可以用到window.URL.createObjectURL()方法,这个方法可以传入File或Blob对象来生成对象URL供mapbox使用。而首先我们需要把base64转化成Blob对象:

// base64 图片字符串
const base64Image = 'data:image/png;base64,iVBORw0KGgoAAAANS...'; 

// 将 base64 转换为 Blob
function base64ToBlob(base64, type = 'image/png') {
    const byteCharacters = atob(base64.split(',')[1]);
    const byteNumbers = new Array(byteCharacters.length);
    for (let i = 0; i < byteCharacters.length; i++) {
        byteNumbers[i] = byteCharacters.charCodeAt(i);
    }
    const byteArray = new Uint8Array(byteNumbers);
    return new Blob([byteArray], { type });
}

// 创建 Blob 对象
const blob = base64ToBlob(base64Image);

我们把二进制的base64对象,通过逐个把字符转化成相应的ASCII码的方式,变成内存相对应的无符号字节数组来创建Blob对象。在创建Blob对象的时候,可以传入一个options参数,并在其中指定MIME类型。下面我们需要把Blob对象,转化为对象URL:

const imageUrl = URL.createObjectURL(blob);

// 添加图像源
this.map.addSource('rasterImageSource', {
    type: 'raster',
    tiles: [imageUrl],
    tileSize: 256 // 根据实际图像尺寸调整
});

// 添加 raster 图层
this.map.addLayer({
    id: 'rasterImageLayer',
    type: 'raster',
    source: 'rasterImageSource'
});

URL.createObjectURL()这个函数支持传入Blob对象,返回的值是一个指向内存中地址的字符串,可以作为url在mapbox中直接使用。

使用完数据之后,最好能释放与之关联的内存。只要对象URL在使用中,就不能释放内存。如果想表明不再使用某个对象URL,则可以把它传给window.URL.revokeObjectURL()。页面卸载时,所有对象URL占用的内存都会被释放。不过,最好在不使用时就立即释放内存,以便尽可能保持页面占用最少资源。