将 svg 转换为 png 时如何包含 CSS 样式

2024-01-11

我创建了一个简单的 SVG 元素,单击按钮时会下载到 png,我的解决方案类似于here https://stackoverflow.com/questions/28226677/save-inline-svg-as-jpeg-png-svg


基本思想是:
1.svg转画布
2.canvas转dataUrl
3.从dataUrl触发下载

问题是,当下载 png 文件时,它不包含应用于 svg 的 css 样式 我的解决方案结果 https://i.stack.imgur.com/wyOAX.png

注意 - 我知道有一个解决方案,可以通过在元素上“内联”移动样式来解决 like here https://stackoverflow.com/questions/33189495/adding-css-style-when-converting-svg-to-png或者通过挖掘 DOM 树并使用递归解决方案getCompatedStyle(元素,null);

问题:
1.这个问题的真正原因是什么以及解决办法。
(GPU加速有什么关系吗?)
2.当使用 Fontface 的自定义字体时,我如何仍然克服这个问题

 <button id="btn">svg to png</button>

  <svg id="svg" width="200" height="200">
    <circle cx="50" cy="50" r="30" />
    <text class="svgTxt" x="0" y="100">Hen's SVG Image</text>
  </svg>
  <canvas id="canvas"  width="200" height="200"></canvas>

my CSS:

  /*adding exo2 font*/
    @font-face {
    font-family: 'exo_2black';
    src: url('./exo2font/Exo2-Black-webfont.eot');
    src: url('./exo2font/Exo2-Black-webfont.eot?#iefix') format('embedded-opentype'),
         url('./exo2font/Exo2-Black-webfont.woff') format('woff'),
         url('./exo2font/Exo2-Black-webfont.ttf') format('truetype'),
         url('./exo2font/Exo2-Black-webfont.svg#exo_2black') format('svg');
    font-weight: normal;
    font-style: normal;

}
/*change circle color depends on window size*/
@media screen and (min-width: 480px) {
    svg circle {
        fill: lightgreen;
    }
}
/*style on the svg text*/
    .svgTxt{
      font-family: 'exo_2black';
      font-size: 30px;
      fill: red;
    }

my code:

  //reference to elements
    var btn = document.querySelector('#btn');
    var svg = document.getElementById('svg');
    var svgTexts = svg.getElementsByTagName('text');
    var canvas = document.getElementById('canvas');
    //Style definitions for svg elements defined in stylesheets are not applied to the generated canvas. This can be patched by adding style definitions to the svg elements before calling canvg.
  //3.trigger download from dataUrl
    function triggerDownload(imgURI) {
      var evt = new MouseEvent('click', {
        view: window,
        bubbles: false,
        cancelable: true
      });

      var a = document.createElement('a');
      a.setAttribute('download', 'hen_saved_image.png');
      a.setAttribute('href', imgURI);
      a.setAttribute('target', '_blank');
      a.dispatchEvent(evt);
    }
    //btn click event
    btn.addEventListener('click', function () {
      // 1.svg to canvas
      var ctx = canvas.getContext('2d');
      var data = (new XMLSerializer()).serializeToString(svg);//serialize the svg element to string
      var DOMURL = window.URL || window.webkitURL || window;
      var img = new Image();
      var svgBlob = new Blob([data], { type: 'image/svg+xml;charset=utf-8' });//A blob object represents a chuck of bytes that holds data of a file.
      var url = DOMURL.createObjectURL(svgBlob);//creates a DOMString containing an URL representing the object given in paramete
      $('svg').append(deletedSVGText);
      img.onload = function () {
        ctx.drawImage(img, 0, 0);
        DOMURL.revokeObjectURL(url);
        // 2.canvas to dataUrl
        var imgURI = canvas
          .toDataURL('image/png')
          .replace('image/png', 'image/octet-stream');// returns a data URI containing a representation of the image in the format specified by the type parameter

        triggerDownload(imgURI);
      };
      img.src = url;
    });

Question 1 (first half): what's the real reason (is the GPU acceleration related in anyway?)

不,GPU 加速与此无关。
最广泛的原因是privacy.

绘制你的svgdrawImage你必须将你的 svg 作为外部文档加载到<img>标签。 SVG 可能是一种相当复杂的资源加载图像格式(它实际上可能需要任何 HTML 文档可能需要的任何类型的资源)。因此,规格中已规定,与以下产品具有相同的安全性:<iframe>元素或<object>或类似的应该适用于<img>内容甚至更严格:

<img>内容不能需要任何外部资源,也不能访问主文档。

问题1(下半场): 以及这个问题的解决方案

您指出了一些已经回答的问题,您也可以将主文档中的所有样式表包含在<style>标记在解析后的 svg 节点中,然后再从中创建 Blob。这里是愚蠢的实现 https://stackoverflow.com/questions/41340468/convert-svg-to-image-in-png

问题2 : “在 Fontface 中使用自定义字体时我如何仍然克服这个问题”

对于外部资源,您必须将其编码为 dataURI,并在创建 Blob 之前将其包含在 svg 节点中。特别是对于字体,您可以设置一个font-face财产在一个<style>元素。

所以最后,你的 svg 会有类似的内容

<defs>
  <style>
    /* all your parsed styles in here */
    @font-face {
     font-family: foo;
     src: url('data:application/font-woff;charset=utf-8;base64,...')
    }
  </style>
</defs>

在您提取其标记之前。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 svg 转换为 png 时如何包含 CSS 样式 的相关文章

  • 为 iOS 应用程序加载基于 SVG 的图像资源

    我从 thenounproject 购买了一个图标作为 SVG 图像 然后我使用一个名为的 macOS 程序Gapplin http gapplin wolfrosch com 将此 SVG 导出为 PNG 图像 它显示为 100x100
  • 如何防止 CFDocument 中的内容中间发生分页?

    我使用 cfdocument 标签从 html css 动态生成 PDF 文件 有些内容块我不想跨越多个页面 经过一番搜索后 我发现根据文档支持 page break inside 样式 然而 在我的测试中 声明 page break in
  • 滚动时输入自动完成位置错误(chrome)

    我在输入文本的默认自动完成功能方面遇到了一些麻烦 滚动时它不会相应移动 我希望自动完成文本保留在输入的正下方 有办法做到这一点吗 我在 Chrome 浏览器版本 57 0 2987 133 中发生这种情况 fiddle https jsfi
  • 当鼠标悬停在伪元素上时触发CSS动画?

    我试图在伪元素悬停时触发 CSS 动画 我目前有 2 个视频 显示鼠标悬停在浏览器的 50 一侧 我想应用类似的效果来为某些文本添加动画效果 我想要 p 标签在移动时向上移动并淡入 p h1 同时以同样的方式标记 就像这个网站一样 http
  • 是否可以使用 Flying Saucer (XHTML-Renderer) 将 css 解析为类路径资源?

    我正在尝试将资源打包到 jar 中 但我无法让 Flying Saucer 在类路径上找到 css 我无法轻松构建 URL 来无缝解决此问题 https stackoverflow com questions 861500 url to l
  • IE 中的 HR 标签 - 删除边框

    在除 IE7 及更低版本之外的其他浏览器中 hr 在 hr 标签周围显示边框 但我不希望它出现 我已经尝试过这个解决方案 但它周围似乎仍然有边框 它看起来像这样 我该如何摆脱它 See http webdesign about com od
  • 扩展位置绝对div超出溢出隐藏div

    我已经好几个月没有做过CSS了 所以我可能会错过一些简单的东西 但无论解决方案是什么 我都无法弄清楚 所以问题就在这里 这是我的代码的简化版本 div style height 100 width 200px div style margi
  • 如何在CSS中制作一个带有边框的可调整大小的心形

    我想要制作一个心形 用户可以将其大小调整为任意宽度和高度 并且边框为 1 像素 我尝试了用纯 CSS 制作的心形 https stackoverflow com a 17386187 1404447 https stackoverflow
  • 在 Fabric.js 中按宽度/高度在另一个画布对象内居中和缩放画布对象

    Goal 将一个对象 水平和垂直 置于另一个对象 矩形或组 的中心canvas via Fabric js或者通过Javascript保持原始对象的长宽比相同 但也不超过父对象的宽度 高度比例 父对象 矩形或组 不会居中于canvas元素
  • @font-face 和 font-variant 是个坏主意吗?

    如果我使用 font face字体和font variant small caps对于相同的选择器 字体将回退到 Safari 中的下一个系统默认字体 我该如何解决这个问题 我一开始在创建一个示例来复制您的问题时遇到了一些麻烦 这让我意识到
  • HTML 元素的默认背景颜色是什么?白色还是透明?

    我只是被一个简单的问题困住了 想弄清楚 HTML 元素的默认背景颜色是什么 是白色的还是透明的 默认背景颜色是透明的 看这里 https developer mozilla org en docs Web CSS background co
  • 如何强制外部 div 扩展到内部 div 的高度?

    我有 ajax 到的数据 div class content 我希望外部 div 扩展到内部 div 的高度 我不知道该怎么做 HTML div class outer div class inner div class content S
  • 删除圆形图像周围的边框

    我有一个圆形图像 png 文件 中间是透明的 我需要将图像内的背景设置为纯色 为此 我将背景设为纯色 然后将border radius 50 但这会产生一条丑陋的小白线 有没有办法摆脱这个问题 或者我必须在图像编辑器中手动为图像着色 div
  • Internet Explorer 中的锯齿状按钮边缘

    如何去除 Internet Explorer 中宽按钮的锯齿状边缘 例如 您还可以通过设置来消除 Windows XP 的按钮样式 以及 Windows 的所有其他版本 background color and or border colo
  • Android:我可以创建一个不是矩形的视图/画布吗?圆形的?

    我有一个圆形视图 悬停在主要内容上方 gt 从屏幕出来的 z 轴方向 当有人点击屏幕时 我希望选择主要内容或悬停在上方的视图 当它覆盖主视图时 到目前为止效果很好 我在透明画布上有一个圆形物品 这意味着您可以看到该圆圈之外的背景的所有内容
  • 嵌套计算操作

    希望这很简单 我想使用CSS calc操作来执行两个计算 我想将宽度设置为等于 100 7 2 但是 如果我尝试在 CSS 计算操作中执行多个操作 则会失败 width calc 100 7 2 如何在一个 CSS 语句中执行多个计算操作
  • 如何在 React Native 上显示 SVG 文件?

    我想显示 svg 文件 我有一堆 svg 图像 但我找不到显示的方式 我尝试使用Image and Use的组成部分反应本机 svg https github com magicismight react native svg但他们不这样做
  • 如何使整个跨度落入新行?

    这个片段显示了我想要的 http jsfiddle net 945Df 3 http jsfiddle net 945Df 3 div class sup strong a href Rosario Santa Fe Argentina a
  • 如何删除标题中的粗体?

    我有一个标题 h1 THIS IS A HEADLINE h1 如何使短语 THIS IS 不加粗 其余部分不做任何更改 我在文本装饰中找不到任何相关标签 标题看起来很粗体 因为它大尺寸 如果您已应用粗体或想要更改行为 您可以执行以下操作
  • 我可以使用 ASP.NET WebForms 母版页在每个内容页中包含不同的 javascript/css 文件吗?

    我有几个使用相同母版页的内容页 它们并不都需要包含在相同的 javascript 和 css 文件中 tag 是否可以更改内容来自内容页面的标签 确实如此 但我建议采取一些不同的做法 我在关闭正文标签的正上方放置了一个内容占位符 然后我填充

随机推荐