从获取的图像创建数据 url
create data url from fetched image
TL;DR
我正在尝试 fetch
和图像,将其转换为 base64,然后将 数据 url 放入 img
' s src
属性,但它不起作用:
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 中查看它时,我得到了这个:
第一个和第三个 link 都有效:
然而,中间link没有:
下面是三个 link 分别对标签执行的操作:
作品:
<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 看起来也太短了。那我做错了什么?
当你有内存中的 blob 时
只需为该 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 的字符串。
了解 blob 到 base64 的转换 here。
但是更优雅的解决方案是createObjectURL.
感谢@dolpsdw 的建议。 window.btoa
没有按照我的预期去做。如果有人试图做同样的事情,将 blob 读入数据 url 的说明在这里:
我创建了这个适合我的程序的包装器,如下所示:
(它甚至为您添加 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:
TL;DR
我正在尝试 fetch
和图像,将其转换为 base64,然后将 数据 url 放入 img
' s src
属性,但它不起作用:
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 中查看它时,我得到了这个:
第一个和第三个 link 都有效:
然而,中间link没有:
下面是三个 link 分别对标签执行的操作:
作品:
<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 看起来也太短了。那我做错了什么?
当你有内存中的 blob 时 只需为该 blob
生成一个 urlvar 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.
})
也许您还想在加载
后撤销 URLURL.revokeObjectURL(objectURL)
为什么 window.btoa 不起作用,因为它仅适用于 base64 的字符串。
了解 blob 到 base64 的转换 here。 但是更优雅的解决方案是createObjectURL.
感谢@dolpsdw 的建议。 window.btoa
没有按照我的预期去做。如果有人试图做同样的事情,将 blob 读入数据 url 的说明在这里:
我创建了这个适合我的程序的包装器,如下所示:
(它甚至为您添加 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: