Html2canvas: Manera de aumentar la resolución de la imagen generada a través de toDataURL

Creado en 10 jul. 2013  ·  58Comentarios  ·  Fuente: niklasvh/html2canvas

Esto es más una solicitud de función. Puedo generar fácilmente el PNG llamando a toDataURL en el canvas devuelto. Pero la calidad de la imagen es bastante borrosa / mala. Busqué en Google y descubrí que, de forma predeterminada, solo devuelve una imagen a 96 ppp. Y no parece haber una forma estándar de mejorar esto. Además, toDataURLHD es experimental y no funciona de ninguna manera.

¿Hay alguna forma de que html2canvas pueda devolver una imagen a una resolución más alta? O incluso si puede proporcionar una forma de renderizar el DOM, puedo usar alguna biblioteca que use el DOM (con todos los estilos calculados aplicados) y luego generar la imagen que desee.

Comentario más útil

+1 para esto. Buscando obtener una imagen con html2canvas para insertar en un PDF, pero obteniendo una calidad borrosa.

Todos 58 comentarios

Sé que se habló de esto en algún momento en otros problemas / solicitudes y alguien había enviado una solicitud de extracción, pero nunca vi que las solicitudes de extracción se fusionaran.

Tengo un método de trabajo que usamos para verificar la densidad de píxeles del dispositivo. Pero esto puede afectar el rendimiento. En su lugar, ¿tal vez queremos tener un parámetro que le diga que renderice con más ppp?

@missing Yeah, un parámetro para especificar el DPI sería increíble.

Además, si no le importa compartir el método de trabajo para la densidad de píxeles del dispositivo, será genial. Mi aplicación principal es simplemente exportar un png de una nube de palabras con un máximo de 50 términos. Así que no estoy tan preocupado por el impacto en el rendimiento en este caso.

¿Su problema es la calidad de la imagen o es un efecto borroso (en algunos casos, algunas imágenes son generadas por html2canvas con efecto borroso)?

@brcontainer Creo que la calidad de la imagen es el problema. Creo. Por ejemplo, con un zoom del 100%, la foto se ve bien, decente. Pero tan pronto como hago zoom incluso un 5%, puedes ver una caída notable en la calidad de la foto. Ver imagen adjunta.
association-cloud-apple-twitter

Solo puedo estar seguro de algo al ver un ejemplo del problema en tiempo de ejecución.

Pruebe el mismo lugar usando http://jsfiddle.net/ y publique el enlace aquí.

[editar]
Si intenta aplicar _zoom_ en un lienzo generado por html2canvas, puede intentar usar (antes de guardar como imagen):

ctx.webkitImageSmoothingEnabled = false;
ctx.mozImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;

Buena suerte

Hola,

Necesitamos una resolución superior a 96DPI. Necesitamos más como 300 DPI.

¿Es esto incluso _posible_ hacer con html2canvas?

Tenemos el mismo problema con la imagen borrosa. Necesitamos cualquier solución que elimine nuestra borrosidad y nos dé un DPI que se vea bien.

¿Alguna idea / sugerencia sobre cómo se podría hacer esto, o alguna forma alternativa de lograr el mismo efecto?

Gracias

@brcontainer Solo tu edito ahora. Hice lo que sugieres y sigo sin suerte con la calidad de imagen. Aquí esta lo que hice -

                var ctx = canvas.getContext('2d');

                ctx.webkitImageSmoothingEnabled = false;
                ctx.mozImageSmoothingEnabled = false;
                ctx.imageSmoothingEnabled = false;

                var rawData = canvas.toDataURL("image/png");

está en el orden incorrecto, debe aplicar "ImageSmoothingEnabled" antes de cambiar el tamaño de la imagen.

Ponga una muestra de su código en http://jsfiddle.net e intentaré editarlo

Hola tios,

Deseo cargar imágenes de alta resolución sin la restricción de 96 ppp de toDataURL. Dado que toDataURLHD aún no está disponible, ¿cómo puedo realizar mi sueño? :-)

Gracias de antemano por cualquier pista

@brcontainer No estoy seguro de entender lo que quiere decir con aplicar el suavizado antes de cambiar el tamaño, porque no voy a cambiar el tamaño de la imagen en absoluto. En cualquier caso, he creado un jsfiddle para que lo veas en http://jsfiddle.net/tankchintan/92mra/4/

¡Tengo muchas ganas de resolver esto! :)

Amigo, estás confundiendo, está el toDataURL que tiene que cambiar de tamaño, tienes que cambiar el tamaño del CANVAS .
Estoy tratando de crear un ejemplo, pero aún no pude hacerlo funcionar.

Hola,

He intentado seguir estas sugerencias para obtener una mejor calidad de imagen y tampoco me queda claro.

brcontainer, ¿es posible que puedas aclarar, o cambiar / crear un violín JS que creó tankchintan, con las ideas de las que estás hablando? Esto no tiene sentido para mí, incluso si creamos una imagen con el doble de tamaño, la pixelación en la imagen aún permanece después de convertir la imagen a 192 DPI.

Hola chicos, ¿hay más comentarios sobre este tema? Estoy experimentando una calidad de imagen extremadamente profesional con html2canvas en comparación con algo como PhantomJS, donde puede configurar zoomFactor (entre otros ajustes) para aumentar la calidad / resolución.

Tengo un problema similar. Tengo el requisito de obtener una instantánea de la página web en un documento PDF para el que estoy usando html2canvas para convertir mi div en una imagen y luego uso iTextsharp para agregar la imagen a un PDF. Sin embargo, la imagen generada parece estar un poco borrosa y hace que sea difícil para el ojo verla constantemente. Quiero saber si puedo crear una imagen de resolución especificada en el momento de creación en html2canvas.

Hola,
Tengo exactamente el mismo requisito que el anterior. y el mismo problema que estoy enfrentando.
"Obtener una instantánea de la página web en un documento PDF para el que estoy usando html2canvas para convertir mi div en una imagen y luego agregar la imagen a un PDF".
Sin embargo, la imagen generada parece estar un poco borrosa.

Seguí las sugerencias anteriores, pero aún así obtengo una imagen borrosa.
aquí en mi código: html2canvas genera una instantánea de la página web que se basa en la resolución del sistema.
Estoy obteniendo la misma "instantánea" de la página web en diferentes tamaños, según la resolución del sistema.

Ejemplo :
tamaño de la imagen: 816x422
tamaño de la imagen: 1193x437
tamaño de la imagen: 1275x437
Aquí mi expectativa es: Dimensión 2000 x 1784 y superior.

¿Es posible obtener esta dimensión de imagen?
por favor dé sus valiosas sugerencias y gracias por su valioso tiempo.

+1 para esto. Buscando obtener una imagen con html2canvas para insertar en un PDF, pero obteniendo una calidad borrosa.

¿Ha intentado usar la matriz de transformación CSS en un parentNode al elemento que desea exportar a una resolución más alta? Esto funciona para mi. Por ejemplo, "transformar: escala (2, 2)"

@mudcube funcionó parcialmente para mí

@brcontainer está funcionando bien para mí

¿Hay alguna solución encontrada? Por favor, comparta cómo mejorar la resolución de una imagen borrosa. Tengo que hacer un pdf.

+1 ¿hay alguna solución / directriz para esto todavía?

alguna solución encontrada?

Chicos, usen transform: scale(2, 2) , funciona.

puedes darme mas detalles?

@matiasinsaurralde justo antes de hacer la captura de pantalla, agregue la clase css .x2 contenga la regla css de arriba al elemento, luego elimine esa clase en html2canvas callback. Obtendrá un elemento de tamaño doble y una captura de pantalla de tamaño doble también. Y es perfecto, por lo que es probable que no observe ningún cambio de tamaño.

image
captura de pantalla cuando intenté seguir tu sugerencia @Ajaxy . creo que el problema está en mi código? tomó tanto tiempo renderizar la página

la escala no aumentó la resolución para mí. Tuve que resolverlo con JS -
https://github.com/niklasvh/html2canvas/issues/379

¿Mucha suerte, chicos?

transform: scale(2, 2); tampoco es la solución para dygraph.js

@premerddyn , vea mi solución en el problema vinculado.
Funciona bien, pero requiere una ampliación antes de la captura de pantalla.
Si mi comentario no es claro, agregaré más explicaciones.

bueno, lo que hice fue hacer un div del doble de tamaño y hacer que la visibilidad colapsara y cada contenido que tenía aquí lo publiqué en ese div y tomé una captura de pantalla.De esa manera, no se pierde claridad de imagen y modifiqué un código de tamaño de fuente para hacerlo Trabajo. Hago que esto funcione bien. Pero mi problema es con el trazo de texto y el fondo de texto de varias líneas.

la escala de 2 funciona para mí, sin embargo, encuentro que la representación está limitada por la resolución / tamaño de la ventana. Si el div escalado es más ancho que la ventana, entonces parte de él se cortará

Entonces, ¿no hay forma de capturar lienzos más grandes que la pantalla?

Ah, de este hilo:

var h = $(element)[0].ownerDocument.defaultView.innerHeight;
    $(element)[0].ownerDocument.defaultView.innerHeight = $(element).height();
    html2canvas($(element)).then(function(canvas) {
        $(element)[0].ownerDocument.defaultView.innerHeight = h;
        //Do whatever you want with your canvas
    }

https://jsfiddle.net/enjoythedaycsk/9L966sdd/1/

Intenté lograr algo de alta resolución en este ejemplo, pero no lo entendí ...

Haga clic en el botón descargar pngx2.

¿Es posible realizar operaciones en el backend, como cuando se hace clic en el botón, el lienzo se convierte en el doble de su tamaño y luego se captura la imagen y luego el lienzo vuelve a su tamaño normal?

Claro, podrías hacer eso. Disparo un lienzo del tamaño que quiero usando el
código proporcionado. Descubrí que obtener el valor puede ser inexacto, así que simplemente
establezca el ancho / alto directamente.

El sábado 7 de mayo de 2016, enjoytheday [email protected] escribió:

https://jsfiddle.net/enjoythedaycsk/9L966sdd/1/

Intenté lograr algo de alta resolución en este ejemplo, pero no obtuve
ese...

Haga clic en el botón descargar pngx2.

¿Es posible realizar operaciones en el backend como cuando se hace clic en el botón?
el lienzo se convierte en el doble de su tamaño y luego se captura la imagen y luego se vuelve a capturar
el lienzo vuelve a su tamaño normal.

-
Estás recibiendo esto porque hiciste un comentario.
Responda a este correo electrónico directamente o véalo en GitHub
https://github.com/niklasvh/html2canvas/issues/241#issuecomment -217634634

La ilustración en curso más larga del mundo
ForeverScape.com http://www.foreverscape.com/ | @foreverscape
https://twitter.com/foreverscape | En Github
https://github.com/vance/foreverscapecore | En las noticias
http://www.foreverscape.com/art/reviews/

@vance , ¿puede establecer esto en el ejemplo de jsfiddle?

https://jsfiddle.net/enjoythedaycsk/9L966sdd/1/

Lo intenté pero no lo configuré yo.

Puede editarlo por completo o puede crear uno nuevo.

Será útil para muchos: bailarina:

Traté de simularlo rápidamente pero no tuve tiempo de arreglar el div de prueba. Capturar algo con transform:scale() no hace nada porque la altura interna del div se ve _NO_ afectada. Por eso es una transformación. Sus propiedades w / h no han cambiado (internamente), que puede probar obteniendo getBoundingClientRect() . Su ancho / alto solo cambia _actualmente_ cuando se ve en el contexto del padre. Tienes que agarrar el contenedor div después de escalarlo.

https://jsfiddle.net/jano9ao4/1/

Me enfrento al mismo problema, ¿hay alguna solución viable? ヾ (´ ・ ・ `。) ノ "

Pude hacer que funcionara, para capturar elementos más grandes que la ventana. Solo recuerde, no puede obtener una imagen "más grande" simplemente a partir de un elemento transformado, porque (para sí mismo), todavía tiene las mismas dimensiones.

Tuve que hacer el mío en un iframe y enviar los datos base64 como un mensaje ... porque al hacer lo siguiente, ROMPE el evento de cambio de tamaño de la ventana.

De nuevo con comentarios:

   //store the original size
    var h = $(element)[0].ownerDocument.defaultView.innerHeight;
    var w = $(element)[0].ownerDocument.defaultView.innerWidth;

   //set the document to the element's size
    $(element)[0].ownerDocument.defaultView.innerHeight = $(element).height();
    $(element)[0].ownerDocument.defaultView.innerWidth = $(element).width();

    html2canvas($(element)).then(function(canvas) {
        //restore the document size
        $(element)[0].ownerDocument.defaultView.innerHeight = h;
        $(element)[0].ownerDocument.defaultView.innerWidth = w;
        //Do whatever you want with your canvas
    }

Escribí la siguiente función para obtener fácilmente una captura de pantalla de mayor DPI de un elemento HTML usando html2canvas.

  • si la altura o el ancho están restringidos (por ejemplo, hay un ancho de cuerpo fijo), las restricciones deben eliminarse durante el procesamiento; el elemento de origen debe poder crecer hasta la escala deseada
  • srcEl debería ser un elemento existente
  • destIMG debe ser un elemento de imagen existente (vacío)
  • dpi deben ser múltiplos de 96
var makeHighResScreenshot = function(srcEl, destIMG, dpi) {
    var scaleFactor = Math.floor(dpi / 96);
    // Save original size of element
    var originalWidth = srcEl.offsetWidth;
    var originalHeight = srcEl.offsetHeight;
    // Save original document size
    var originalBodyWidth = document.body.offsetWidth;
    var originalBodyHeight = document.body.offsetHeight;

    // Add style: transform: scale() to srcEl
    srcEl.style.transform = "scale(" + scaleFactor + ", " + scaleFactor + ")";
    srcEl.style.transformOrigin = "left top";

    // create wrapper for srcEl to add hardcoded height/width
    var srcElWrapper = document.createElement('div');
    srcElWrapper.id = srcEl.id + '-wrapper';
    srcElWrapper.style.height = originalHeight*scaleFactor + 'px';
    srcElWrapper.style.width = originalWidth*scaleFactor + 'px';
    // insert wrapper before srcEl in the DOM tree
    srcEl.parentNode.insertBefore(srcElWrapper, srcEl);
    // move srcEl into wrapper
    srcElWrapper.appendChild(srcEl);

    // Temporarily remove height/width constraints as necessary
    document.body.style.width = originalBodyWidth*scaleFactor +"px";
    document.body.style.height = originalBodyHeight*scaleFactor +"px";

    window.scrollTo(0, 0); // html2canvas breaks when we're not at the top of the doc, see html2canvas#820
    html2canvas(srcElWrapper, {
        onrendered: function(canvas) {
            destIMG.src = canvas.toDataURL("image/png");
            srcElWrapper.style.display = "none";
            // Reset height/width constraints
            document.body.style.width = originalBodyWidth + "px";
            document.body.style.height = originalBodyHeight + "px";
        }
    });
};

Uso:

var src = document.getElementById("screenshot-source");
var img = document.getElementById("screenshot-img");
makeHighResScreenshot(src, img, 192); // DPI of 192 is 4x resolution (2x normal DPI for both width and height)

¿Descubrió que al hacer esto también se rompen los controladores de eventos window.onresize? Por esta razón, tuve que hacer todo esto dentro de un iframe y publicar el resultado usando parent.window.postMessage (data) para devolver el contenido. Esto solo me importa porque es una aplicación móvil y es fundamental tener un incendio de tamaño normal.

@vance : En mi caso, no necesito ni uso ninguna de esas cosas; de hecho, estoy usando esto para

Descubrí otra forma de obtener una imagen de alta resolución que no necesita cambiar el tamaño del cuerpo. Sin embargo, tiene que posicionar absolutamente el elemento fuente debido a un error en html2canvas (# 790, # 820, # 893, # 922, etc.). Basado en el código retina de @MisterLamb .

function takeHighResScreenshot(srcEl, destIMG, scaleFactor) {
    // Save original size of element
    var originalWidth = srcEl.offsetWidth;
    var originalHeight = srcEl.offsetHeight;
    // Force px size (no %, EMs, etc)
    srcEl.style.width = originalWidth + "px";
    srcEl.style.height = originalHeight + "px";

    // Position the element at the top left of the document because of bugs in html2canvas. The bug exists when supplying a custom canvas, and offsets the rendering on the custom canvas based on the offset of the source element on the page; thus the source element MUST be at 0, 0.
    // See html2canvas issues #790, #820, #893, #922
    srcEl.style.position = "absolute";
    srcEl.style.top = "0";
    srcEl.style.left = "0";

    // Create scaled canvas
    var scaledCanvas = document.createElement("canvas");
    scaledCanvas.width = originalWidth * scaleFactor;
    scaledCanvas.height = originalHeight * scaleFactor;
    scaledCanvas.style.width = originalWidth + "px";
    scaledCanvas.style.height = originalHeight + "px";
    var scaledContext = scaledCanvas.getContext("2d");
    scaledContext.scale(scaleFactor, scaleFactor);

    html2canvas(srcEl, { canvas: scaledCanvas })
    .then(function(canvas) {
        destIMG.src = canvas.toDataURL("image/png");
        srcEl.style.display = "none";
    });
};

Uso:

var src = document.getElementById("screenshot-src");
var img = document.getElementById("screenshot-img");
takeHighResScreenshot(src, img, 2); // This time we provide desired scale factor directly, no more messing with DPI

EDITAR: Se redujo la piratería usando el posicionamiento absoluto en lugar de mover el elemento y ajustar los márgenes, gracias a @ jason-o-matic por la sugerencia.

esto funciona con la versión más reciente (0.5.0-alpha). pero no 0.4.1

si quieres resolver este problema en 0.4.1, tienes que jugar con el tamaño del lienzo.

Solo una nota rápida para cualquiera que use la solución de

No puede tener ningún elemento "relativo" que envuelva el elemento que desea volcar en la pantalla, sin importar qué tan alto en el xtree estén. Deben cambiarse a estático durante la duración de la descarga de pantalla para que el elemento que desea aparezca en realidad en 0,0 en relación con la ventana, no en un DIV circundante.

Me tomó varias horas resolver esto, así que espero que esto ayude a alguien a evitar los mismos problemas.

Muchachos, buenas tardes,
¿Alguien tiene una solución jsfiddle of @airdrummingfool ? Estoy tratando de implementarla en mi proyecto sin suerte. Un ejemplo práctico sería genial para mí para entender cómo funciona esto y me ayudaría mucho a intentar implementarlo en mi proyecto.

Muchas gracias por cualquier ayuda que se pueda brindar.

¡Hola a todos! Estoy tratando de usar la solución @airdrummingfool . Pero me sale un molesto error. Dentro del elemento del que quiero obtener la imagen, hay un elemento y al realizar el procedimiento, el elemento img queda en blanco y el src se ignora. ¿Sabes cómo puedo solucionar esto? ¿Alguien ha enfrentado este problema antes con html2canvas?

¡Gracias de antemano a este hilo! ¡¡Me está salvando !! :D

EDITAR: También obtengo solo la mitad de la imagen renderizada. Pero la resolución se ve perfecta xD

¡Arreglado el problema de la imagen! ¡UseCORS no estaba habilitado! Pero todavía obtengo solo la mitad de la imagen renderizada.

¡Excelente! La mitad de la imagen puede deberse a un problema de renderizado fuera del lienzo . También hice una solicitud de extracción para agregar resolución / escala a html2canvas , puede que le resulte más fácil de usar que la solución @airdrummingfool .

Hasta que se fusionen con html2canvas, puede obtener mi compilación personalizada con ambos y algunas otras correcciones de errores aquí .

Hola @eKoopmans. Gracias por tu respuesta. Me las arreglé para arreglar la mía multiplicando la altura por 2. Pero, creo que obtengo una imagen más grande con espacios en blanco arriba y abajo ... así que ... voy a probar la tuya e informarte en unos minutos. !

OM (F) G @eKoopmans .. Tu ha funcionado fuera de la caja. Muchas gracias hombre. Esa solicitud de extracción ... deberían aceptarla ahora. Hay MUCHAS personas que desean esta opción de dpi para html2canvas.

Cierre a favor del # 1087

@airdrummingfool ... Gracias. Eso funciona perfecto.

La última versión de html2canvas le ofrece la opción de escalar. Funciona muy bien.

html2canvas (elemento, {
escala: 2
});

Para la representación de múltiples páginas en PDF a partir de contenido de imagen y HTML, la configuración de scale: 1 podría solucionar el problema de resolución y, al mismo tiempo, evitar que las imágenes excedan el borde del pdf.

Creo que esto ayuda, usé html2canvas

Descargar PDF() {
var doc = new jsPDF ({
formato: "a4"
});

html2canvas (document.getElementById ("pdf-doc"), {
escala: "5"
}). luego (lienzo => {
this.imgFile = lienzo;
doc.addImage (este.imgFile, "JPEG", 5, 5, 200, 285);
doc.save ("nombre de archivo" + ".pdf");
});
}

¿Fue útil esta página
0 / 5 - 0 calificaciones