【问题标题】:canvas.toDataUrl returns "data:;" when canvas.width/height is too largecanvas.toDataUrl 返回“数据:;”当 canvas.width/height 太大时
【发布时间】:2020-11-24 11:01:02
【问题描述】:

我需要做一个 svg 导出 png 图像功能。 首先我生成svg到base64,base64头类型也是svg+xml,然后

var image=new Image();
image.src=base64Code;
image.onload = function() {
      var canvas = document.createElement('canvas');
      var context = canvas.getContext('2d');
      canvas.width = image.width;
      canvas.height = image.width;
      context.drawImage(image, 0, 0);
      png = canvas.toDataURL("image/png",1);
}`

我的canvas.width/height 可能很大。
当我使用canvas.toDataURL 时,它返回"data:;"。 当canvas.width/height更合理时,结果是正确的。

有什么好的方法可以解决这个问题吗?或者使用javascript将svg+xml转换为.png?

【问题讨论】:

  • 当你说非常大时,它有多大?比这些max sizes 大吗?如果是这样,是的,不要使用画布。否则,您可以尝试canvas.toBlob 方法,理论上该方法对内存的影响较小,因此应该能够返回更大的图像。但是,如果您能够提供服务器端转换,然后继续使用它,您将获得比使用 javascript 更好的结果,例如 batik。
  • 所以实际上 toBlobtoDataURL 有相同的限制(我的 chrome 大约 16380*16380 和我的 FF 大约 11150*11150)。但是一件有趣的事情是,对于toDataURL,chrome 确实返回了你得到的字符串,而 FF 确实抛出了一个 NSIndexError,对于toBlob,chrome 确实在回调中返回 null,而 FF 甚至不执行回调, 也不会抛出任何错误...
  • 我尝试使用蜡染将 svg 文件生成为 png 文件或将 svg 代码生成为 png 文件,但是在我的 svg 中,它有 标签,该标签有 标签,当我生成 svg 不显示
  • No batik is not able to render html (which is in your foreignObject) 因为这些你唯一的选择是一个 HTML 渲染器,它也能够渲染 SVG(我可以想到顶部的网络浏览器我的头)。但随后我们又回到了画布的最大尺寸问题 + 只有 FF、chrome 和 Edge(?) 支持在画布上渲染 foreignObject 而不会污染它以供导出的事实。所以你至少必须为你的画布设置一个最大尺寸(你也可以将图像分成多个,然后在服务器上合并它们),或者你可以尝试从无头浏览器服务器端抓取屏幕截图。跨度>
  • phantomjs 应该可以做到。虽然我从来没有用 foreignObjects 测试过

标签: javascript java html canvas svg


【解决方案1】:

Canvas 元素具有最大尺寸,这在不同的浏览器实现中会有所不同。 您可以在this Q/A 中找到这些最大尺寸的良好列表。

它们对导出方法也有限制。 在我的 Chrome 中,toDataURL 返回的 data:; 与您在 16380 * 16380 宽的画布上获得的相同,而我的 Firefox 确实在 11150 * 11150NS_ERROR_FAILURE /强>。 其他浏览器可能有不同的值,具体取决于它们自己的实现。

因此,如果您真的想通过画布,则必须将画布的大小限制在这些最大区域内。

现在,如果您可以在服务器端进行转换,则可以使用它。 Batik 被认为是一个很好的 SVG UA 并且应该能够正确地转换您的 SVG,除非在 SVG 的 <foreignObject> 元素中也有 HTML 要呈现。

在这种情况下,像 phantomjs 这样的无头浏览器允许对渲染页面进行真实截图似乎是最好的方法。

另一种方法是将大型 SVG 绘制到较小的画布上,然后在服务器端或通过字节操作合并生成的 PNG 图像(可能需要一些额外的工作)。

【讨论】:

  • 我尝试将大画布限制为小画布,并在服务器端合并生成的 png,非常感谢
【解决方案2】:

<!DOCTYPE html>
<html>
<body>

<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>

<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

ctx.strokeRect(5, 5, 25, 15);
ctx.scale(2, 2);
ctx.strokeRect(5, 5, 25, 15);
</script> 

</body>
</html>

HTML 画布 scale() 方法

你可以用这个方法,也许它可以工作

返回'数据:;'可能是网址太大

【讨论】:

    猜你喜欢
    • 2015-07-16
    • 1970-01-01
    • 2014-09-12
    • 1970-01-01
    • 2014-01-03
    • 1970-01-01
    • 2014-03-27
    • 2018-09-12
    相关资源
    最近更新 更多