Javascript 使用D3和BLOB将svg渲染为图像

Javascript 使用D3和BLOB将svg渲染为图像,javascript,html,d3.js,svg,Javascript,Html,D3.js,Svg,我正在尝试做一种反向验证码,最后我希望能够输入长达500个字符的文本行,并对单词进行一些基本的验证码模糊处理,但仍然可读。但我还希望生成一个可以下载的图像,而不是svg 我已经成功地为文本创建了效果并呈现了svg,我还找到了一个使用d3将其呈现为datauri并将blob呈现为图像的示例。我一直在尝试将svg插入示例d3渲染发生的位置,但我认为我做得不对 这是我的工作文本2captcha gen,其中包含部分不工作的d3/svg/blob to image,我将引用html 这里是链接到工作d

我正在尝试做一种反向验证码,最后我希望能够输入长达500个字符的文本行,并对单词进行一些基本的验证码模糊处理,但仍然可读。但我还希望生成一个可以下载的图像,而不是svg

我已经成功地为文本创建了效果并呈现了svg,我还找到了一个使用d3将其呈现为datauri并将blob呈现为图像的示例。我一直在尝试将svg插入示例d3渲染发生的位置,但我认为我做得不对

这是我的工作文本2captcha gen,其中包含部分不工作的d3/svg/blob to image,我将引用html

这里是链接到工作d3 blob到图像的链接。我也会引用这个html。


路径{
行程:#000;
填充不透明度:.8;
}
另存为图像
SVG数据URL:
通过HTML5画布将SVG转换为PNG数据URL:
SVG通过HTML5画布转换为PNG数据URL,然后使用以下命令转换为文件名:
可变宽度=960,
高度=500;
var m=5,//系列数
n=90;//值的数目
//将随机数据生成五个数组。
var data=d3.range(m).map(函数(){
返回d3.range(n).map(函数(){
返回Math.random()*100 | 0;
});
});
var x=d3.scale.linear()
.domain([0,n-1])
.范围([0,宽度]);
变量y=d3.scale.ordinal()
.域(d3.范围(m))
.范围点([0,高度],1);
var color=d3.scale.ordinal()
.范围([“98abc5”、“8a89a6”、“7b6888”、“6b486b”、“a05d56”);
var area=d3.svg.area()
.插入(“基础”)
.x(函数(d,i){返回x(i);})
.y0(函数(d){return-d/2;})
.y1(函数(d){返回d/2;});
var svg=d3.选择(“svg”).追加(“svg”)
.attr(“宽度”,宽度)
.attr(“高度”,高度);
svg.selectAll(“路径”)
.数据(数据)
.enter().append(“路径”)
.attr(“转换”,函数(d,i){return“translate(0,+y(i)+”);})
.style(“填充”,函数(d,i){返回颜色(i);})
.attr(“d”,区域);
d3.选择(“保存”)。在(“单击”,函数()上{
var html=d3.select(“svg”)
.attr(“版本”,1.1)
.attr(“xmlns”)http://www.w3.org/2000/svg")
.node().parentNode.innerHTML;
//log(html);
var imgsrc='数据:image/svg+xml;base64'+btoa(html);
var img=“”;
d3.选择(“#svgdataul”).html(img);
var canvas=document.querySelector(“canvas”),
context=canvas.getContext(“2d”);
var图像=新图像;
image.src=imgsrc;
image.onload=函数(){
drawImage(image,0,0);
//将其保存并作为实际文件名使用
二进制blob();
var a=document.createElement(“a”);
a、 下载=“sample.png”;
a、 href=canvas.toDataURL(“image/png”);
var pngimg='';
d3.选择(“#pngdataul”).html(pngimg);
a、 单击();
};
});
函数binaryblob(){
var byteString=atob(document.querySelector(“canvas”).toDataURL().replace(//^data:image\/(png | jpg);base64,/,“”);//wtf是atob??https://developer.mozilla.org/en-US/docs/Web/API/Window.atob
var ab=新阵列缓冲区(byteString.length);
var ia=新的UINT8阵列(ab);
for(var i=0;i

非常感谢您查看我的线程,我并不擅长编码。您的选择是错误的。当你执行

var html = d3.select("svg")
    .attr("version", 1.1)
    .attr("xmlns", "http://www.w3.org/2000/svg")
    .node().parentNode.innerHTML;
parentNode
元素,它的
innerHTML
是页面上的所有内容,而不仅仅是
元素。通过界面,您可以更简洁地完成整个过程:

var svgNode = d3.select('svg').node();
var html = new XMLSerializer().serializeToString(svgNode);
这还将处理
xmlns
属性(不需要
版本)


第二部分是
btoa()
不是文件转换器,而是编码器。区别在于浏览器甚至在显示之前就将其解码回SVG。这与你想要实现的目标背道而驰。您可以使用下面示例中的代码,也可以查看细节不同但基本相同的代码,即将SVG转换为光栅图像。

非常感谢您,先生。这有助于我渲染图像!
<!DOCTYPE html>
<meta charset="utf-8">
<style>

path {
  stroke: #000;
  fill-opacity: .8;
}

</style>
<body>
    <div id="svg"></div>
    <button id="save">Save as Image</button>
    <h2>SVG dataurl:</h2>
    <div id="svgdataurl"></div>

    <h2>SVG converted to PNG dataurl via HTML5 CANVAS:</h2>
    <div id="pngdataurl"></div>

    <h2>SVG converted to PNG dataurl via HTML5 CANVAS and then converted into a filename using :</h2>
    <div id="pngdataurl"></div>

    <canvas width="960" height="500" style="display:none"></canvas>

<script src="http://d3js.org/d3.v3.min.js"></script>
<script>

var width = 960,
    height = 500;

var m = 5, // number of series
    n = 90; // number of values

// Generate random data into five arrays.
var data = d3.range(m).map(function() {
  return d3.range(n).map(function() {
    return Math.random() * 100 | 0;
  });
});

var x = d3.scale.linear()
    .domain([0, n - 1])
    .range([0, width]);

var y = d3.scale.ordinal()
    .domain(d3.range(m))
    .rangePoints([0, height], 1);

var color = d3.scale.ordinal()
    .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56"]);

var area = d3.svg.area()
    .interpolate("basis")
    .x(function(d, i) { return x(i); })
    .y0(function(d) { return -d / 2; })
    .y1(function(d) { return d / 2; });

var svg = d3.select("#svg").append("svg")
    .attr("width", width)
    .attr("height", height);

svg.selectAll("path")
    .data(data)
  .enter().append("path")
    .attr("transform", function(d, i) { return "translate(0," + y(i) + ")"; })
    .style("fill", function(d, i) { return color(i); })
    .attr("d", area);




d3.select("#save").on("click", function(){
  var html = d3.select("svg")
        .attr("version", 1.1)
        .attr("xmlns", "http://www.w3.org/2000/svg")
        .node().parentNode.innerHTML;

  //console.log(html);
  var imgsrc = 'data:image/svg+xml;base64,'+ btoa(html);
  var img = '<img src="'+imgsrc+'">'; 
  d3.select("#svgdataurl").html(img);

    var canvas = document.querySelector("canvas"),
        context = canvas.getContext("2d");

    var image = new Image;
    image.src = imgsrc;
    image.onload = function() {
      context.drawImage(image, 0, 0);

      //save and serve it as an actual filename
    binaryblob();

      var a = document.createElement("a");
      a.download = "sample.png";
      a.href = canvas.toDataURL("image/png");

       var pngimg = '<img src="'+a.href+'">'; 
       d3.select("#pngdataurl").html(pngimg);

      a.click();
    };

});


function binaryblob(){
    var byteString = atob(document.querySelector("canvas").toDataURL().replace(/^data:image\/(png|jpg);base64,/, "")); //wtf is atob?? https://developer.mozilla.org/en-US/docs/Web/API/Window.atob
    var ab = new ArrayBuffer(byteString.length);
    var ia = new Uint8Array(ab);
    for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
    }
    var dataView = new DataView(ab);
    var blob = new Blob([dataView], {type: "image/png"});
    var DOMURL = self.URL || self.webkitURL || self;
    var newurl = DOMURL.createObjectURL(blob);

    var img = '<img src="'+newurl+'">'; 
  d3.select("#img").html(img);
}
</script>
var html = d3.select("svg")
    .attr("version", 1.1)
    .attr("xmlns", "http://www.w3.org/2000/svg")
    .node().parentNode.innerHTML;
var svgNode = d3.select('svg').node();
var html = new XMLSerializer().serializeToString(svgNode);