【问题标题】:How to get background color of SVG converted properly into Canvas如何将 SVG 的背景颜色正确转换为 Canvas
【发布时间】:2016-07-31 02:15:36
【问题描述】:

我正在使用 canvg 库将 d3 svg 对象转换为画布并将其显示为图像 (png)。

生成的图像具有透明背景,这不是我想要的。我需要这个有白色背景的。

所以我尝试设置 svg 元素的背景颜色。查看 svg 元素时很好,但转换后的图像仍然是透明的。 我也尝试过改变画布对象的背景,但这也不起作用。

第一种方法(svg):

var svg = d3.select(".chart").append("svg").attr("style","background: white;")...

第二次接近(画布):

canvg(document.getElementById('canvas'), $("#chart").html());

var canvas = document.getElementById('canvas');
canvas.style.background = 'white';
var img = canvas.toDataURL('image/png');
document.write('<img src="' + img + '"/>');  

有谁知道,我必须在哪个对象上设置背景颜色,以便在 png 图像中正确转换它?

编辑:根据 ThisOneGuys 回答中提到的信息,我找到了这个解决方案。

var svg = d3.select(".chart").append("svg") ...

svg.append("rect")
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", "white"); 

使用附加的矩形,我得到了我需要的东西:)

【问题讨论】:

    标签: javascript canvas d3.js svg


    【解决方案1】:

    添加&lt;rect&gt; 是一种解决方案,另一种解决方案是在调用“canvg”方法后渲染背景颜色。

    您可以从 canvas API 调用每个绘图操作来在您的光栅化版本上绘图,因此可以使用 ctx.fillRect 填充背景。要使新绘图出现在背景中,您只需将globalCompositeOperation 属性设置为destination-over

    var $container = $('#svg-container'),
          content = $container.html().trim(),
          canvas = document.getElementById('svg-canvas');
    
         // Since we will edit the canvas afterward, we need to remove that #!~$^ default mouseEvent listener
        canvg(canvas, content, {ignoreMouse: true});
         // now you've rendered your svg, you can draw the background on the canvas
        var ctx = canvas.getContext('2d');
    
         // all drawings will be made behind the already painted pixels
        ctx.globalCompositeOperation = 'destination-over'
          // set the color
        ctx.fillStyle = $container.find('svg').css('background-color');
         // draw the background
        ctx.fillRect(0, 0, canvas.width, canvas.height);
    
    
        var theImage = canvas.toDataURL('image/png');
        $('#svg-img').attr('src', theImage);
    svg {
      background-color: lightgreen;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/rgbcolor.js"></script>
    <script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/canvg.js"></script>
    <section>
      <header>
        <h1>SVG:</h1>
      </header>
      <div id='svg-container'>
        <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
          <circle cx="60" cy="70" r=50 style="fill:blue;stroke:pink;stroke-width:5;fill-opacity:0.1;stroke-opacity:0.9" />
        </svg>
      </div>
    </section>
    <section>
      <header>
        <h1>Canvas:</h1>
      </header>
      <canvas id="svg-canvas"></canvas>
    </section>
    <section>
      <header>
        <h1>PNG:</h1>
      </header>
      <img id="svg-img" />
    </section>

    【讨论】:

    • 感谢您澄清,如何在画布对象上执行此操作。 +1
    【解决方案2】:

    我以前也遇到过。如您所知,CSS 不会通过 get 放入 DOM,因此转换不会读取它。所以你必须改用内联样式。但是你目前的做法是不正确的。

    所以不要使用:

    .attr("style","background: white;").
    

    你必须像这样设置样式:

    .style('fill', 'white'); 
    

    应该没问题:)

    【讨论】:

    • 这并没有给我正确的背景颜色,而是我的轴标签文本现在是白色的。但在转换后的图像中背景仍然是透明的
    • 嗯。问题肯定出在 svg 而不是画布上的样式上。你有没有在你看过的地方有其他一些与之冲突的样式?
    • 你能设置一个简单的小提琴来解决你的问题吗?那我可以自己去看看:)
    • 如果您查看此链接:w3.org/TR/SVG/styling.html 继续造型。您会注意到您不能在 svg 上使用背景样式。但是您可以像我提到的那样进行填充。阅读可能会有所帮助
    • 我会接受您的回答,因为它会引导我找到解决方案。我用答案更新我的问题
    【解决方案3】:

    我会用rect 在 svg 中“绘制”背景:

    <html>
    
    <head>
      <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
      <script data-require="jquery@2.2.0" data-semver="2.2.0" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
      <script src="https://rawgit.com/gabelerner/canvg/master/canvg.js"></script>
    </head>
    
    <body>
      <div class="chart" id="chart" style="width: 50%; margin: 0 auto;"></div>
      <!-- d3 code -->
      <script type="text/javascript">
        var svg = d3.select(".chart").append("svg")
        .attr("id", "mysvg")
        .attr("width", 500)
        .attr("height", 500);
        
        svg.append('rect')
          .attr('width', 500)
          .attr('height', 500)
          .style("fill", "red");
        
        svg.selectAll('.bar')
          .data([1,2,3,4])
          .enter()
          .append('rect')
          .attr('y', function(d,i){
            return d * 50;
          })
          .attr('height', function(d,i){
            return 500 - (d * 50);
          })
          .attr('width', 50)
          .attr('x', function(d,i){
            return i * 100;
          })
          .style('fill', 'steelblue');
        
      </script>
      <canvas id="canvas" width="200" height="200"></canvas>
      <script type="text/javascript">    
        var canvas = document.getElementById('canvas');
        canvg(document.getElementById('canvas'), $('#chart').html());
        var img = canvas.toDataURL('image/png');
        document.write('<img src="' + img + '"/>');
      </script>
    </body>
    
    </html>

    【讨论】:

    • 赞成,和我在 5 分钟前发现的一样:D
    猜你喜欢
    • 2011-11-19
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-06
    • 2021-11-20
    • 2022-01-07
    相关资源
    最近更新 更多