04 mayo, 2023

Un bookmarklet para integrar imágenes en un único archivo HTML

Tengo por costumbre leer libros en formato EPUB con la app Moon+ reader, tanto en el móvil (amoled con fondo negro y filtro de pantalla antireflejos) como en mi ebook de 10". Sin embargo, en ocasiones el libro que quiero leer no está disponible ese formato. Un caso que ya me ha ocurrido en ocasiones es que el libro esté online para ser leido en el navegador, como éste en el que se han preocupado incluso de dejarlo en un único archivo. Existen conversores online que reciben un único archivo HTML y genera un EPUB, como éste o éste. Sin embargo, las imágenes enlazadas no se convierten, por lo que el libro generado no está completo.

 He pensado en incrustar las imágenes enlazadas en el propio documento HTML convirtiéndolas a DATA-URIs. Para ello he creado el siguiente bookmarklet: imgs2dataurl (puedes arrastrarlo a la barra de marcadores para poder ejecutarlo sobre cualquier página que tengas cargada). Al acabar el proceso, si guardas la página como archivo HTML único, las imágenes se guardarán también en el mismo archivo, lo que permite que sean adjuntadas al convertirlo a EPUB.

javascript: (async function(){
  [...document.querySelectorAll('[loading=lazy]')].forEach(a=>a.removeAttribute('loading'));
  const imgs=[...document.querySelectorAll("img[src$='.jpg'],img[src$='.png']")];
  imgs.forEach(i=>{
      if (i.src.startsWith("data:")) return;
    const canvas=document.createElement("canvas");
    canvas.width=i.naturalWidth;
    canvas.height=i.naturalHeight;
    const ctx=canvas.getContext("2d");
    ctx.drawImage(i,0,0);
    const src= canvas.toDataURL();
    if (src!='data:,') i.src= src; else console.log(i.naturalWidth,i.naturalHeight,canvas.width);
  });
  const svgs= [...document.querySelectorAll("img[src$='.svg']")];
  svgs.forEach(async i=>{
    const t= await fetch(i.src);
    const text= await t.text();
    i.src='data:image/svg+xml,'+encodeURIComponent(text)
  });
})();

El código tiene tres partes. La primera se asegura de cargar todas las imágenes que especifiquen una carga lazy, o sea que se vayan cargando conforme se visualizan en el navegador. Así me aseguro de que todas las imágenes estén cargadas. De lo contrario la conversión a Data-uris fallaría al no tener imagen disponible.

A continuación realizo la conversión de las imágenes PNG y JPG usando un elemento canvas que incluye una función toDataURL para hacer la conversión directa. El resultado de esa función se guarda directamente en el img.src sustituyendo efectivamente la referencia a la imagen a cargar por la misma imagen ya codificada. Y por último hago el mismo proceso con los SVG.

Enjoy!

0 comentarios:

Publicar un comentario



Últimos links en indiza.com