从获取的图像创建数据网址

问题描述 投票:0回答:2

TL; DR

我正在尝试fetch和图像,将其转换为base64,然后将data url放入imgsrc属性,但它不起作用:

async function ajax(id) {
  const tag = document.getElementById(id);
  const path = tag.getAttribute("data-src");
  const response = await fetch(path);
  const blob = await response.blob();
  const base64 = window.btoa(blob);
  const content = `data:image/jpeg;base64,${base64}`;
  tag.setAttribute("src", content);
}

遵循细节[以及其他一些方法,[[做。


我一直在尝试不同的延迟加载方式:

$ mkdir lazy $ cd lazy $ wget https://upload.wikimedia.org/wikipedia/commons/7/7a/Lone_Ranger_and_Silver_1956.jpg # any other example image

现在创建一个名为index.html的文件:

<script> // this works function setAttribute(id) { const tag = document.getElementById(id); const path = tag.getAttribute("data-src"); tag.setAttribute("src", path); } // this doesn't work for some reason async function ajax(id) { const tag = document.getElementById(id); const path = tag.getAttribute("data-src"); const response = await fetch(path); const blob = await response.blob(); const base64 = window.btoa(blob); const content = `data:image/jpeg;base64,${base64}`; tag.setAttribute("src", content); } // this works too async function works(id) { const tag = document.getElementById(id); const path = tag.getAttribute("data-src"); const response = await fetch(path); const blob = await response.blob(); const content = URL.createObjectURL(blob); tag.setAttribute("src", content); } </script> <a href="javascript: setAttribute('example');">set attribute</a><br /> <a href="javascript: ajax('example');">data url</a><br /> <a href="javascript: works('example');">object url</a><br /> <img id="example" data-src="Lone_Ranger_and_Silver_1956.jpg"></img><br />

并在该文件夹中启动服务器:

$ python -m SimpleHTTPServer # or whichever local webserver

然后,当我用Chrome浏览器看到它时:

enter image description here

第一个和第三个链接均起作用:

enter image description here

但是,中间链接没有:

enter image description here

这是三个链接分别对标记的作用:

作品:

<img id="example" data-src="Lone_Ranger_and_Silver_1956.jpg" src="Lone_Ranger_and_Silver_1956.jpg">

不起作用:

<img id="example" data-src="Lone_Ranger_and_Silver_1956.jpg" src="data:image/jpeg;base64,W29iamVjdCBCbG9iXQ==">

作品:

<img id="example" data-src="Lone_Ranger_and_Silver_1956.jpg" src="blob:http://localhost:8000/736a9e18-c30d-4e39-ac2e-b5246105c178">

非工作示例中的数据url看起来也太短。那我在做什么错?
javascript html image base64 data-uri
2个回答
0
投票
当内存中有斑点时只需为该Blob生成一个URL

var url = urlCreator.createObjectURL(blob)

然后使用JavaScript创建新的IMG并调用decode方法

const img = new Image(); img.src = url; img.decode() .then(() => { document.body.appendChild(img); }) .catch((encodingError) => { // Do something with the error. })
也许您还想在加载后撤销URL

URL.revokeObjectURL(objectURL)


关于window.btoa为什么不起作用的原因,因为它仅适用于base64的字符串。

了解有关base64会话here的Blob。但是,createObjectURL是一个更优雅的解决方案。


0
投票
感谢@dolpsdw的建议。 window.btoa并没有达到我的预期。如果有人尝试做同样的事情,请在此处将Blob读入数据url的说明:https://stackoverflow.com/a/18650249/5203563

我已经创建了一个适合我程序的包装器,如下所示:

(它甚至为您添加了data:image/jpeg;base64,部分,并从Blob中得出了mime类型)

function readBlob(b) { return new Promise(function(resolve, reject) { const reader = new FileReader(); reader.onloadend = function() { resolve(reader.result); }; // TODO: hook up reject to reader.onerror somehow and try it reader.readAsDataURL(b); }); } async function ajax(id) { const tag = document.getElementById(id); const path = tag.getAttribute("data-src"); const response = await fetch(path); const blob = await response.blob(); // const base64 = window.btoa(blob); // const content = `data:image/jpeg;base64,${base64}`; const content = await readBlob(blob); tag.setAttribute("src", content); }

这给了我期望的更长的数据URL:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.