Genera una imagen desde un nodo DOM usando lienzo HTML5 y SVG.
Bifurcación de dom a imagen con código más fácil de mantener y algunas características nuevas.
instalación npm: guardar html en imagen
/* ES6 */import * as htmlToImage from 'html-to-image';import { toPng, toJpeg, toBlob, toPixelData, toSvg } from 'html-to-image';/* ES5 */var htmlToImage = require(' html a imagen');
Todas las funciones de nivel superior aceptan nodos DOM y opciones de representación, y devuelven una promesa cumplida con la URL de datos correspondiente:
aSvg
arribaPng
a Jpeg
aBlob
aPixelData
Vaya con los siguientes ejemplos.
Obtenga una URL de datos codificada en base64 de una imagen PNG y muéstrela de inmediato:
var nodo = document.getElementById('mi-nodo');htmlToImage.toPng(nodo) .then(function (dataUrl) {var img = nueva Imagen();img.src = dataUrl;document.body.appendChild(img); }) .catch(function (error) {console.error('¡Ups, algo salió mal!', error); });
Obtenga una URL de datos codificada en base64 de una imagen PNG y descárguela (usando la descarga):
htmlToImage.toPng(document.getElementById('mi-nodo')) .entonces(función (dataUrl) {descargar(dataUrl, 'mi-nodo.png'); });
Obtenga una imagen blob PNG y descárguela (usando FileSaver):
htmlToImage.toBlob(document.getElementById('mi-nodo')) .luego(función (blob) {ventana.saveAs(blob, 'mi-nodo.png'); });
Guarde y descargue una imagen JPEG comprimida:
htmlToImage.toJpeg(document.getElementById('mi-nodo'), {calidad: 0,95}) .then(function (dataUrl) {var link = document.createElement('a');link.download = 'mi-nombre-imagen.jpeg';link.href = dataUrl;link.click(); });
Obtenga una URL de datos SVG, pero filtre todos los elementos <i>
:
filtro de función (nodo) { return (node.tagName! == 'i');}htmlToImage.toSvg(document.getElementById('mi-nodo'), { filtro: filtro }) .entonces(función (dataUrl) {/* hacer algo */ });
Obtenga los datos de píxeles sin procesar como Uint8Array con cada 4 elementos de la matriz que representan los datos RGBA de un píxel:
var nodo = document.getElementById('mi-nodo');htmlToImage.toPixelData(nodo) .then(function (píxeles) {for (var y = 0; y < node.scrollHeight; ++y) { for (var x = 0; x < node.scrollWidth; ++x) {pixelAtXYOffset = (4 * y * node.scrollHeight) + (4 * x);/* pixelAtXY es un Uint8Array[4] que contiene valores RGBA del píxel en (x, y) en el rango 0..255 */pixelAtXY = pixels.slice(pixelAtXYOffset, pixelAtXYOffset + 4}); });
Obtenga un HTMLCanvasElement y muéstrelo de inmediato:
htmlToImage.toCanvas(document.getElementById('mi-nodo')) .luego(función (lienzo) {document.body.appendChild(lienzo); });
Una función que toma el nodo DOM como argumento. Debería devolver verdadero si el nodo pasado debe incluirse en la salida. Excluir el nodo significa excluir también a sus hijos.
No llamado en el nodo raíz.
Un valor de cadena para el color de fondo, cualquier valor de color CSS válido.
Ancho y alto en píxeles que se aplicarán al nodo antes de renderizar.
Un objeto cuyas propiedades se copiarán al estilo del nodo antes de renderizar. Es posible que desee consultar esta referencia para conocer los nombres JavaScript de las propiedades CSS.
Un número entre 0
y 1
que indica la calidad de la imagen (por ejemplo, 0.92
=> 92%
) de la imagen JPEG.
El valor predeterminado es 1.0
( 100%
)
Configúrelo en verdadero para agregar la hora actual como una cadena de consulta a las solicitudes de URL para habilitar la prevención de caché.
El valor predeterminado es false
Una URL de datos para una imagen de marcador de posición que se utilizará cuando falle la recuperación de una imagen.
El valor predeterminado es una cadena vacía y representará áreas vacías para imágenes fallidas.
Se probó en los últimos Chrome y Firefox (49 y 45 respectivamente al momento de escribir este artículo), y Chrome tuvo un rendimiento significativamente mejor en árboles DOM grandes, posiblemente debido a su soporte SVG de mayor rendimiento y al hecho de que admite la propiedad CSSStyleDeclaration.cssText
.
Internet Explorer no es (ni será) compatible, ya que no admite la etiqueta SVG <foreignObject>
.
Safari no es compatible porque utiliza un modelo de seguridad más estricto en la etiqueta <foreignObject>
. La solución sugerida es utilizar toSvg
y renderizar en el servidor.
Actualmente solo se utiliza la biblioteca estándar, pero asegúrese de que su navegador admita:
Promesa
Etiqueta SVG <foreignObject>
Es posible que algún día exista (¿o tal vez ya exista?) una forma simple y estándar de exportar partes del HTML a una imagen (y entonces este script solo puede servir como evidencia de todos los obstáculos que tuve que superar para obtener tal algo obvio hecho) pero no he encontrado ninguno hasta ahora.
Esta biblioteca utiliza una característica de SVG que permite tener contenido HTML arbitrario dentro de la etiqueta <foreignObject>
. Entonces, para representar ese nodo DOM por usted, se siguen los siguientes pasos:
Clonar el nodo DOM original de forma recursiva
Calcule el estilo para el nodo y cada subnodo y cópielo en el clon correspondiente
y no olvides recrear pseudoelementos, ya que no están clonados de ninguna manera, por supuesto.
Insertar fuentes web
encuentre todas las declaraciones @font-face
que podrían representar fuentes web
analizar las URL de los archivos, descargar los archivos correspondientes
codificación base64 y contenido en línea como URL de datos
concatene todas las reglas CSS procesadas y colóquelas en un elemento <style>
, luego adjúntelo al clon
Insertar imágenes
incrustar URL de imágenes en elementos <img>
imágenes en línea utilizadas en la propiedad CSS background
, de manera similar a las fuentes
Serializar el nodo clonado a XML
Envuelva XML en la etiqueta <foreignObject>
, luego en SVG y luego conviértalo en una URL de datos
Opcionalmente, para obtener contenido PNG o datos de píxeles sin procesar como Uint8Array, cree un elemento de imagen con SVG como fuente y renderícelo en un lienzo fuera de la pantalla que también haya creado, luego lea el contenido del lienzo.
¡Hecho!
Si el nodo DOM que desea renderizar incluye un elemento <canvas>
con algo dibujado en él, debe manejarse bien, a menos que el lienzo esté contaminado; en este caso, la renderización no tendrá éxito.
El procesamiento fallará en DOM enormes debido a que el límite de dataURI varía.
Las solicitudes de extracción y las estrellas son bienvenidas.
Para errores y solicitudes de funciones, cree un problema.