当前位置: 首页 > 面试题库 >

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

阎乐池
2023-03-14
问题内容

我创建了一个简单的SVG元素,单击按钮时将其下载到png,我的解决方案与此类似

基本思想是:
1.svg到画布
2.canvas到dataUrl
3.trigger从dataUrl下载

问题是,当下载png文件时,它不包括应用于svg的css样式

注意-我知道有一个workingaround解决方案通过移动方式“内联”上的元素
喜欢这里或通过下挖DOM树,并使用递归解决方案 的getComputedStyle(元素,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>

我的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;
    }

我的代码:

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

问题答案:

问题1(上半部分): 真正的原因 是什么(无论如何,GPU加速是否相关?)

不,GPU加速与它无关。
最广泛的原因是 隐私

要绘制svg,drawImage您必须将svg作为外部文档加载到<img>标签内。SVG可能是用于加载资源的非常复杂的图像格式(它实际上可能需要任何HTML文档可能需要的任何类型的资源)。因此,已在规范中指出,与<iframe>元素<object>或类似元素相同的安全性应适用于<img>内容,甚至更为严格:

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

问题1(下半部分)以及此问题的解决方案

您指出了一些已经回答过的SO问题,也可以在从中<style>创建Blob之前,仅将主文档中的所有样式表包括在已解析的svg Node内的标签内

问题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>

本身,然后再提取其标记。



 类似资料:
  • 问题内容: 我在将简单的PNG转换为JPEG格式时遇到问题。我正在使用以下代码: … … 我最后遇到一个JAI异常-> java.lang.RuntimeException:只能写入1或3字节的字节数据。在com.sun.media.jai.codecimpl.JPEGImageEncoder.encode(JPEGImageEncoder.java:148)… 退出选项。有什么建议吗? 问题答案

  • 问题内容: 我具有以下功能,可以将PDF转换为一系列图像(每页一个图像): 这可以很好地工作,性能并没有那么快,但这并不重要。我的问题与内存消耗有关。假设我要转换一个较长的PDF(Apple的10-Q,长达51页): 到最后一页的末尾,内存使用量一直增加到〜11GB! 我还注意到一些注意事项: 当我通过Instruments运行此程序时,它出乎意料地显示没有泄漏。两个大记忆猪是和。它们似乎没有在两

  • 问题内容: 如何以编程方式将SVG文件转换为PDF?(在生成PDF之前,我需要在某些方面进行更改,因此仅使用工具进行预转换就不够了。) 理想情况下,使用Java但Perl或PHP也可以。 显然,我基本上是在考虑使用Java的Apache FOP和Batik。但是,无论我搜索多长时间,都无法找到有关该操作方法的简单介绍。诸如SVGConverter之类的内容具有“为能够转换部分或全部GraphicC

  • 我正在尝试从HTML生成Java格式的pdf文件。HTML代码包含一个svg标记,该标记由Google Charts API生成,用于显示柱状图。 我试着用飞碟R8这样做: 结果是生成的PDF,其中包含图表的轴值,但不包含图表本身;即不包括图表图像。 任何想法或建议都会非常有帮助。 谢谢,肖恩

  • 问题内容: 我在ttf文件中有一种字体,想要生成文本转换为路径的SVG。我不需要图像(因此使用imagettftext或Image Magick字体渲染功能是不够的),我需要可以放大和缩小的形状,我想丢失有关所用字体的信息,并且不想在其中引用它SVG文件(因此此处不能使用字体声明)。可能吗? 问题答案: 我创建了自己的类来处理SVG字体文件并将文本转换为字形。使用示例: 结果示例: 我班的代码: