Skip to main content

Display Blob as Image

接口返回的是图片的二进制,一个 Blob 对象。用 <img> 展示时,需要将返回的 Blob 转换成一个 URL,才可以放到 img 的 src 使用。

URL.createObjectURL()

使用 URL.createObjectURL() 可以将返回的 Blob 转换成一个 URL。

const imageURL = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSw0gWlEimLsPylCKAm95y1K27fCdzXEHGhXYTfEWXo&s"

fetch(imageURL).then((res) => {
  return res.blob()
}).then((blob) => {
  const imageObjectURL = URL.createObjectURL(blob);
  document.querySelector("#img").src = imageObjectURL
})

需要注意的是每次调用都会生成一个新的 URL,哪怕是同一个图片。当文档 unloaded 时,这些生成的 URL 才会被销毁。为了避免 URL 被大量创建造成内存问题,最好在不需要这些 URL 的时候用 URL.revokeObjectURL() 将 URL 释放。

createObjectURL.webp
图1  使用 createObjectURL 生成的图片效果。<img> src 是一个 blob: 开头的 URL。

FileReader.readAsDataURL()

另一种方法是通过 FileReader 的 API,将返回的 Blob 转换成 Base64 显示。

readAsDataURL 方法会读取指定的 BlobFile 对象。读取操作完成的时候, readyState 会变成已完成 DONE ,并触发 loadend 事件,同时 result 属性将包含一个 data:URL 格式的字符串(base64 编码)以表示所读取文件的内容。

const imageURL = "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSw0gWlEimLsPylCKAm95y1K27fCdzXEHGhXYTfEWXo&s"

function blob2Base64(blob) {
  const reader = new FileReader();
  reader.readAsDataURL(blob);

  return new Promise((resolve) => {
    reader.onloadend = () => {
      resolve(reader.result)
    };
  })
}

fetch(imageURL).then((res) => {
  return res.blob()
}).then(async (blob) => {
  document.querySelector("#img").src = await blob2Base64(blob)
})
FileReader.webp
图2  使用 FileReader 生成的图片效果。<img> src 是一个 data:image/jpeg 开头的 URL。
Webmentions (加载中...)

如果你想回应这篇文章,可以在你的文章或社交媒体帖子中链接这篇文章,然后提交你的 URL,你的回应随后会显示在此页面上。 (关于 Webmention)