создать URL-адрес данных из извлеченного изображения - PullRequest
0 голосов
/ 25 октября 2019

TL; DR

Я пытаюсь fetch и изображение, преобразовать его в base64 и поместить url данных в атрибут img 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, я получаю это:

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-адрес данных в нерабочем примере также выглядит слишком коротким. Так что я делаю не так?

Ответы [ 2 ]

0 голосов
/ 26 октября 2019

Спасибо за предложение @dolpsdw. window.btoa не делает то, что думал. Если кто-то пытается сделать то же самое, инструкции по считыванию большого двоичного объекта в URL-адрес данных приведены здесь: https://stackoverflow.com/a/18650249/5203563

Я создал эту обертку, которая вписывается прямо в мою программу следующим образом:

(он даже добавляет в data:image/jpeg;base64, часть для вас и определяет тип MIME из BLOB-объекта)


  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

0 голосов
/ 25 октября 2019

Когда у вас есть бланк памяти Просто создайте URL для этого блоба

var url = urlCreator.createObjectURL(blob)

Затем создайте новое IMG с JavaScript и вызовите decode method

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)


О том, почему окно .btoa не работает, потому что он предназначен только для строк в base64.

Читайте о разговорах BLOB-объектов в base64 здесь . Но это более элегантное решение createObjectURL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...