简体   繁体   English

HTML2canvas 生成模糊图像

[英]HTML2canvas generates Blurry images

I am using jsPDF and it uses html2canvas to generate an image from some html element and insert on the.pdf file.我正在使用 jsPDF,它使用 html2canvas 从一些 html 元素生成图像并插入到 .pdf 文件中。 But there is a problem on html2canvas, it generates blurry images from the html.但是 html2canvas 有一个问题,它从 html 生成模糊的图像。 See example below:请参见下面的示例:

HTML content: HTML 内容:

http://puu.sh/7SZz4.png http://puu.sh/7SZz4.png

html2canvas generated image: html2canvas 生成的图片:

http://puu.sh/7SZAT.png http://puu.sh/7SZAT.png

Is there any way to fix it or is there any better option to get the image form html?有什么办法可以修复它,或者有没有更好的选择来获取 html 的图像?

thanks!谢谢!

you can use scale options in html2canvas.您可以在 html2canvas 中使用缩放选项。

In the latest release, v1.0.0-alpha.1, you can use the scale option to increase the resolution (scale: 2 will double the resolution from the default 96dpi).在最新版本 v1.0.0-alpha.1 中,您可以使用 scale 选项来增加分辨率(scale: 2 将使分辨率从默认的 96dpi 增加一倍)。

// Create a canvas with double-resolution.
html2canvas(element, {
    scale: 2,
    onrendered: myRenderFunction
});
// Create a canvas with 144 dpi (1.5x resolution).
html2canvas(element, {
    dpi: 144,
    onrendered: myRenderFunction
});

I had this problem because I was on a retina display.我有这个问题,因为我在视网膜显示器上。 I solved in by using MisterLamb's solution here .我在这里使用MisterLamb 的解决方案解决了这个问题

$(window).load(function () {

    var scaleBy = 5;
    var w = 1000;
    var h = 1000;
    var div = document.querySelector('#screen');
    var canvas = document.createElement('canvas');
    canvas.width = w * scaleBy;
    canvas.height = h * scaleBy;
    canvas.style.width = w + 'px';
    canvas.style.height = h + 'px';
    var context = canvas.getContext('2d');
    context.scale(scaleBy, scaleBy);

    html2canvas(div, {
        canvas:canvas,
        onrendered: function (canvas) {
            theCanvas = canvas;
            document.body.appendChild(canvas);

            Canvas2Image.saveAsPNG(canvas);
            $(body).append(canvas);
        }
    });
});

HTML and PNG without scaling无缩放的 HTML 和 PNG

在此处输入图片说明

HTML and PNG with scaling带缩放功能的 HTML 和 PNG

在此处输入图片说明

I was facing this problem and i solved it by using domtoimage instead of html2canvas .我面临这个问题,我通过解决它domtoimage而不是html2canvas

This HTML2CANVAS solution was not working good for me i know the scale option does increase the target div's size before capturing it but it won't work if you have something inside that div which won't resize eg in my case it was canvas for my editing tool.这个HTML2CANVAS解决方案对我来说不是很好,我知道缩放选项在捕获它之前会增加目标 div 的大小,但是如果你在那个 div 里面有一些不会调整大小的东西,它就不起作用,例如在我的情况下它是我的画布编辑工具。

Anyway for this i opted for domtoimage and trust me i think that this is the best solution of them all.无论如何,为此我选择了domtoimage并相信我,我认为这是所有解决方案中的最佳解决方案。

I didn't had to face any problem of html2canvas for example:我不必面对html2canvas任何问题,例如:

need to be at the top of webpage so html2canvas can capture the shot completely and low dpi problem需要在网页的顶部,以便html2canvas可以完全捕获镜头和低 dpi 问题

function print()
{
    var node = document.getElementById('shirtDiv');
    var options = {
        quality: 0.95
    };

    domtoimage.toJpeg(node, options).then(function (dataUrl)
    {
        var doc = new jsPDF();
        doc.addImage(dataUrl, 'JPEG', -18, 20, 240, 134.12);
        doc.save('Test.pdf');
    });
}

Cdn for dom to image:用于 dom 映像的 Cdn:

https://cdnjs.com/libraries/dom-to-image https://cdnjs.com/libraries/dom-to-image

Cdn for jspdf: jspdf的cdn:

https://cdnjs.com/libraries/jspdf https://cdnjs.com/libraries/jspdf

I have found out my problem.我发现了我的问题。 Happens that my screen is a Retina Display, so when the canvas2html will render the HTML, due to the difference of pixel density on retina screen, the image is rendered blurred.碰巧我的屏幕是 Retina Display,所以当 canvas2html 渲染 HTML 时,由于 Retina 屏幕上的像素密度差异,图像渲染模糊。

Found out the solution here:在这里找到了解决方案:

https://github.com/cburgmer/rasterizeHTML.js/blob/master/examples/retina.html https://github.com/cburgmer/rasterizeHTML.js/blob/master/examples/retina.html

This is what fixed it for me.这就是为我修复它的原因。 And it wasn't because I was using a retina display (because I don't have one):这不是因为我使用的是视网膜显示器(因为我没有):

https://github.com/niklasvh/html2canvas/issues/576 https://github.com/niklasvh/html2canvas/issues/576

Just change the getBounds() method in html2canvas.js with this one:只需使用以下方法更改 html2canvas.js 中的 getBounds() 方法:

 function getBounds (node) {
        if (node.getBoundingClientRect) {
            var clientRect = node.getBoundingClientRect();
            var width = node.offsetWidth == null ? clientRect.width : node.offsetWidth;
            return {
                top   : Math.floor(clientRect.top),
                bottom: Math.floor(clientRect.bottom || (clientRect.top + clientRect.height)),
                right : Math.floor(clientRect.left + width),
                left  : Math.floor(clientRect.left),
                width : width,
                height: node.offsetHeight == null ? clientRect.height : node.offsetHeight
            };
        }
        return {};
    }

solution is very simple, after X hours of testing.经过X小时的测试,解决方案非常简单。

Set your ALL div's 2x higher, your IMG 2x higher, and finally set html zoom on 0.5, or if you want better quality yet, set 3x higher (in this case the html zoom must be 0.33) or more, (the original image sizes are assumed to be larger).将 ALL div 的 2 倍高,IMG 高 2 倍,最后将 html 缩放设置为 0.5,或者如果您还想要更好的质量,则将 html 缩放设置为高 3 倍(在这种情况下,html 缩放必须为 0.33)或更多,(原始图像大小假设更大)。

For example:例如:

HTML HTML

<body>
 <div class="pdf">
   <img src="image.jpg">
 </div>
</body>

CSS before之前的 CSS

body {
    background: #b2b2b2;
}
.pdf {
   background: #fff;
   /* A4 size */
   width: 842px;
   height: 595px;
 }
img {
   width: 300px;
   height: 200px;
}

CSS after (only changes) CSS之后(仅更改)

html {
   zoom: 0.5;
}

.pdf {
   /* A4 size before . 2 */
   width: 1684; 
   height: 1190px; 
 }
img { /* size before . 2 */
   width: 600px;
   height: 400px;
}

AND here is my result:这是我的结果:

PDF before PDF after PDF 之前PDF 之后

If anyone is still looking for a solution to work for them I had success by setting scale: 5. Check it out here in their documentation.如果有人仍在寻找适合他们的解决方案,我通过设置比例获得了成功: 5. 在他们的文档中查看此处。 https://html2canvas.hertzen.com/configuration https://html2canvas.hertzen.com/configuration

dom-to-image library worked perfect for me! dom-to-image 库非常适合我!

 import domtoimage from "dom-to-image"; // Convert dom to image function const exportAsImage = async (el, imageFileName) => { domtoimage.toPng(el).then(function (dataUrl) { const image = dataUrl; downloadImage(image, imageFileName); }).catch(function (error) { console.error("oops, something went wrong,"; error); }); }, // dowload image function const downloadImage = (blob. fileName) => { const fakeLink = window.document;createElement("a"). fakeLink:style = "display;none;". fakeLink;download = fileName. fakeLink;href = blob. document.body;appendChild(fakeLink). fakeLink;click(). document.body;removeChild(fakeLink). fakeLink;remove(); }; export default exportAsImage;

enter code here在此处输入代码

Try the Canvas2Image library, it gives a better quality image at least for me div to image (fiddle) .试试 Canvas2Image 库,它至少为我提供了更好质量的图像div to image (fiddle)

    html2canvas($("#widget"), {
        onrendered: function(canvas) {
            theCanvas = canvas;
            Canvas2Image.saveAsPNG(canvas);  // Convert and download as image with a prmompt. 
        }
    });

Good luck!祝你好运!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM