Html2canvas: 提高通过 toDataURL 生成的图像的分辨率的方法

创建于 2013-07-10  ·  58评论  ·  资料来源: niklasvh/html2canvas

这更像是一个功能请求。 通过在返回的canvas上调用toDataURL ,我可以轻松生成 PNG。 但是图像的质量相当模糊/差。 我做了一些谷歌搜索,发现默认情况下它只返回 96 dpi 的图像。 并且似乎没有改善这一点的标准方法。 另外toDataURLHD是实验性的,并没有任何作用。

有没有办法html2canvas可以以更高分辨率返回图像? 或者,即使它可以提供一种获取正在呈现的 DOM 的方法,我也可以使用一些使用 DOM(应用了所有计算样式)的库,然后生成我想要的任何图像。

最有用的评论

+1 为此。 希望获得带有 html2canvas 的图像以插入到 PDF 中,但质量模糊。

所有58条评论

我知道在其他问题/请求中的某个时候有人讨论过这个问题,并且有人提交了拉取请求,但我从未看到拉取请求合并。

我有一个我们用来检查设备像素密度的工作方法。 但这可能会影响性能。 相反,也许我们想要一个参数来告诉它以更高的 dpi 呈现?

@missing是的,指定 DPI 的参数会很棒。

此外,如果您不介意分享设备像素密度的工作方法,那会很酷。 我的主要应用程序是仅导出最多 50 个术语的词云的 png。 所以我不太关心这个问题的表现。

您的问题是图像质量还是模糊效果(在某些情况下,某些图像是由 html2canvas 生成的具有模糊效果)?

@brcontainer我认为图像质量是问题所在。 我认为。 例如,在 100% 缩放时,照片看起来还不错。 但只要我放大 5%,您就会发现照片质量明显下降。 请参阅附图。
association-cloud-apple-twitter

我只能确定在运行时看到问题的例子。

使用http://jsfiddle.net/尝试相同的地方,并在此处发布链接。

[编辑]
如果您尝试在由 html2canvas 生成的画布中应用 _zoom_,您可以尝试使用(在保存为图像之前):

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

祝你好运

你好,

我们需要比 96DPI 更高的分辨率。 我们需要更多像 300 DPI。

这甚至_可能_与html2canvas有关吗?

我们在图像模糊方面也有同样的问题。 我们需要任何解决方案,这将消除我们的模糊性,并为我们提供看起来不错的 DPI。

关于如何做到这一点的任何想法/建议,或实现相同效果的任何替代方法?

谢谢

@brcontainer我现在只是你的编辑。 我做了你的建议,但仍然没有图像质量。 这是我所做的 -

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

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

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

顺序错误,您必须在调整图像大小之前应用“ImageSmoothingEnabled”。

将您的代码示例放在http://jsfiddle.net 中,我会尝试对其进行编辑

嗨,大家好,

我希望上传没有 toDataURL 96dpi 约束的高分辨率图像。 既然toDataURLHD还没有可用,我如何实现我的梦想? :-)

提前感谢您的任何提示

@brcontainer我不确定我是否理解在调整大小之前应用平滑是什么意思,因为我根本没有调整图像大小。 无论如何,我已经创建了一个 jsfiddle 供您查看http://jsfiddle.net/tankchintan/92mra/4/

真的很期待解决这个问题! :)

朋友,您感到困惑,必须调整toDataURL大小,您必须调整CANVAS
我正在尝试创建一个示例,但仍然无法使其工作。

你好,

我一直在尝试遵循这些建议以获得更好的图像质量,但我也不清楚。

brcontainer,您是否可以根据您所谈论的想法来澄清或更改/创建一个由 tankchintan 创建的 JS 小提琴? 这对我来说毫无意义,即使我们以 2 倍的尺寸创建图像,在我们将图像转换为 192 DPI 后,图像中的像素仍然存在。

大家好,有没有关于这个问题的更多反馈? 与 PhantomJS 相比,我使用 html2canvas 体验到非常专业的图像质量,您可以在其中设置zoomFactor (以及其他调整)以提高质量/分辨率。

我有一个类似的问题。 我需要将网页的快照转换为 PDF 文档,我使用 html2canvas 将我的 div 转换为图像,然后使用 iTextsharp 将图像添加到 PDF 中。 但是,生成的图像似乎有点模糊,使眼睛难以持续观看。 我想知道是否可以在创建时在 html2canvas 中创建指定分辨率的图像。

你好,
我的要求与上述完全相同。 和我面临的同样问题。
“将网页快照获取到 PDF 文档中,我正在使用 html2canvas 将我的 div 转换为图像,然后将图像添加到 PDF 中。”
但是,生成的图像似乎有点模糊。

我遵循了上述建议,但仍然得到模糊的图像。
在我的代码中:html2canvas 根据系统分辨率生成网页快照。
根据系统分辨率,我获得了不同大小的相同网页“快照”。

例子 :
图像尺寸:816x422
图像尺寸:1193x437
图像尺寸:1275x437
这里我的期望是:2000 x 1784 尺寸及以上。

是否有可能获得这个尺寸的图像。
请提出您宝贵的建议,感谢您抽出宝贵的时间。

+1 为此。 希望获得带有 html2canvas 的图像以插入到 PDF 中,但质量模糊。

您是否尝试过在 parentNode 上使用 CSS 变换矩阵到您希望以更高分辨率导出的元素? 这对我有用。 例如“变换:缩放(2, 2)”

@mudcube为我解决了部分问题

@brcontainer对我来说很好用

有没有找到解决办法?? 请分享如何提高模糊图像的分辨率我必须制作它的pdf

+1 对此有任何解决方案/指南吗?

找到任何解决方案?

伙计们,使用transform: scale(2, 2)就行了。

你能提供更多细节吗?

@matiasinsaurralde在制作屏幕截图之前,将包含 css 规则的 css 类.x2从上方添加到元素,然后在html2canvas回调中删除该类。 您还将获得双倍尺寸的元素和双倍尺寸的屏幕截图。 它是无缝的,因此您可能不会观察到任何调整大小。

image
当我尝试遵循您的建议@Ajaxy时的屏幕截图。 我认为问题出在我的代码上? 渲染页面花了这么长时间

比例并没有增加我的分辨率。 不得不用JS解决它 -
https://github.com/niklasvh/html2canvas/issues/379

有幸运的人吗?

transform: scale(2, 2);也不是 dygraph.js 的解决方案

@premerddyn ,请参阅我在链接问题中的解决方案。
它运行良好,但需要在截图前放大。
如果我的评论不清楚,我会添加更多解释

好吧,我所做的是制作一个两倍大小的 div 并使其可见性折叠,我在这里的每个内容都张贴到该 div 并截取了屏幕截图。这样没有图像清晰度损失,我调整了一些字体大小代码以使其工作。我觉得这个工作正常。但我的问题是文本笔画和多行文本背景。

按 2 缩放对我有用,但是,我发现渲染受窗口分辨率/大小的限制。 如果缩放的 div 比窗口宽,那么它的一部分将被切断

那么,有没有办法捕捉比屏幕大的画布?

啊,从这个线程:

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/

我试图在这个例子中实现高分辨率的东西,但没有得到...

点击下载pngx2按钮..

是否可以在后端进行操作,例如单击按钮时画布变成其大小的两倍,然后捕获图片,然后画布再次恢复到常规大小。

当然,你可以这样做。 我使用我想要的大小触发画布
提供的代码。 我发现获取值可能不准确,所以我只是
直接设置宽度/高度。

上周六,2016年5月7日,enjoytheday [email protected]写道:

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

我试图在这个例子中实现高分辨率的东西,但没有得到
那...

点击下载pngx2按钮..

是否可以在后端进行操作,例如单击按钮时
画布变成两倍大小,然后捕获图片,然后再次
画布被恢复到正常尺寸..


您收到此消息是因为您发表了评论。
直接回复此邮件或在 GitHub 上查看
https://github.com/niklasvh/html2canvas/issues/241#issuecomment -217634634

世界上最长的正在进行的插图
ForeverScape.com http://www.foreverscape.com/ | @永远的风景
https://twitter.com/foreverscape | 在 Github 上
https://github.com/vance/foreverscapecore | 在新闻中
http://www.foreverscape.com/art/reviews/

@vance你能在 jsfiddle 例子中设置这个吗?

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

我试过了,但不是我设置的。

您可以完全编辑它,也可以创建新的。

这将对许多 :dancer 有所帮助:

我试图快速模拟它,但没有时间修复测试 div。 用transform:scale()捕获一些东西不会做任何事情,因为 div 的内部高度_不_受影响。 这就是为什么它是一个转换。 它的 w/h 属性没有改变(内部),您可以通过获取getBoundingClientRect()来测试。 在父上下文中查看时,它的宽度/高度仅_实际上_发生了变化。 您必须在缩放后抓取容器 div。

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

我也遇到了同样的问题,有什么可行的解决办法吗?ヾ(´・・`。)ノ"

我能够让它工作,捕捉比窗口大的元素。 请记住,您不能简单地从转换后的元素中获得“更大”的图像,因为(对于它本身),它仍然具有相同的尺寸。

我必须在 iframe 中执行我的操作并将 base64 数据作为消息发送回...因为执行以下操作会中断窗口调整大小事件。

再次评论:

   //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
    }

我编写了以下函数,以便使用 html2canvas 从 HTML 元素轻松获取更高 DPI 的屏幕截图。

  • 如果高度或宽度受到限制(例如,有固定的主体宽度),则必须在处理过程中移除这些限制——源元素必须能够增长到所需的比例
  • srcEl应该是现有元素
  • destIMG应该是一个现有的(空的)图像元素
  • dpi应该是 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";
        }
    });
};

用法:

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)

您是否发现这样做也会破坏 window.onresize 事件处理程序? 出于这个原因,我必须在 iframe 中完成所有这些操作,并使用 parent.window.postMessage(data) 将结果发回以返回内容。 这对我来说很重要,因为它是一个移动应用程序,并且有 onresize fire 是至关重要的。

@vance :在我的情况下,我不需要或使用任何这些东西 - 我实际上是用它来解决 HTML-to-PDF 渲染器中的错误。 我很想看看你的方法的完整例子,它似乎更灵活。

我想出了另一种方法来获得不需要调整身体大小的高分辨率图像。 但是,由于 html2canvas 中的错误(#790、#820、#893、#922 等),它确实必须绝对定位源元素。 基于@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";
    });
};

用法:

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

编辑:由于@jason-o-matic 的建议,使用绝对定位而不是实际移动元素和调整边距减少了hackiness。

这适用于最新版本(0.5.0-alpha)。 但不是 0.4.1

如果你想在 0.4.1 中解决这个问题,你必须调整画布大小。

对于使用@airdrummingfool的修复程序的任何人

您不能让任何“相关”元素包装您希望屏幕转储的元素,无论它们在 xtree 上多远。 它们需要在屏幕转储期间切换到静态,以便您想要的元素实际上出现在相对于窗口的 0,0 处,而不是周围的 DIV。

我花了几个小时来解决这个问题,所以我希望这可以帮助人们避免同样的问题。

各位下午好
有没有人有@airdrummingfool解决方案的

非常感谢您提供的任何帮助。

嗨,大家好! 我正在尝试使用@airdrummingfool解决方案。 但我得到一个恼人的错误。 在我想从中获取图像的元素中,有一个元素并且在执行该过程时,img 元素变为空白并且 src 被忽略。 你知道我该如何解决这个问题吗? 有没有人在使用 html2canvas 之前遇到过这个问题?

提前感谢这个线程! 这是在救我!! :D

编辑:我也只渲染了一半的图像。 但是分辨率看起来很完美 xD

修复了图片问题!! 未启用 useCORS! 但我仍然只渲染了一半的图像。

伟大的! 半幅图像可能是由于画布外渲染问题造成的。 我还提出了向 html2canvas 添加分辨率/缩放的拉取请求,您可能会发现它比@airdrummingfool解决方案更易于使用。

直到这些GET合并到html2canvas,你可以用这两个和其他一些bug修正得到我的自定义生成这里

嗨@eKoopmans。 感谢您的回答。 我只是设法通过将高度乘以 2 来修复我的。但是,我想我得到了一个更大的图像,上面和下面都有空白......所以......我会尝试你的并在几分钟内报告!

OM(F)G @eKoopmans .. 你的开箱即用。 非常感谢人。 那个拉取请求……他们现在应该接受它。 有很多人想要 html2canvas 的这个 dpi 选项。

关闭支持#1087

@airdrummingfool ......谢谢。 这工作完美。

最新版本的 html2canvas 为您提供了缩放选项。 效果很好。

html2canvas(元素,{
规模:2
});

对于来自 html 和图像内容的多页 pdf 渲染,设置scale: 1可能会解决分辨率问题,同时避免图像超出 pdf 边框。

我认为这有帮助,我使用了 html2canvas

下载pdf(){
var doc = 新的 jsPDF({
格式:“a4”
});

html2canvas(document.getElementById("pdf-doc"), {
规模:“5”
}).那么(画布 => {
this.imgFile = 画布;
doc.addImage(this.imgFile, "JPEG", 5, 5, 200, 285);
doc.save("文件名" + ".pdf");
});
}

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

yasergh picture yasergh  ·  5评论

diego-rey picture diego-rey  ·  3评论

Loki180 picture Loki180  ·  4评论

anthonymejia picture anthonymejia  ·  4评论

rrutkows picture rrutkows  ·  4评论