如何在Google图表中获得带有svg内图像的png(base64)? [英] How can I get png(base64) with images inside of svg in Google Charts?

查看:71
本文介绍了如何在Google图表中获得带有svg内图像的png(base64)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在svg中获得base64图像?检查我从另一个问题中获得的小提琴。如果您看到第二张图片,则不会生成覆盖该栏的图片。

  var chart = new google.visualization.ColumnChart (的document.getElementById( 'chart_survey')); 
$ b $([fill ='#FFFFFF'])。each(function(index,element){
var svgimg = document.createElementNS('http://www.w3 .org / 2000 / svg','image');
svgimg.setAttributeNS(null,'x',element.x.baseVal.value);
svgimg.setAttributeNS(null,'y', element.y.baseVal.value);
svgimg.setAttributeNS(null,'width',element.width.baseVal.value);
svgimg.setAttributeNS(null,'height',element.height。 baseVal.value);
svgimg.setAttributeNS(null,'preserveAspectRatio','none');
svgimg.setAttributeNS('http://www.w3.org/1999/xlink','href ','$ {application.contextPath} /images/textura/patt.gif');
$(element).parent()。append(svgimg);
});
$ b $('#test').val(chart.getImageURI())


解决方案

为了保存这个svg到一个png,它保持链接< image> ,那么你必须首先将每个< image> href 编码为一个dataURL。

编辑



我重写了原始摘要在编辑历史记录中找到)




  • 我将< image> 标签更改为<使用> 。这导致了更小的内存使用量。

  • 我还为IE11添加了一个回退功能,它接受将外部图像编码为数据URL,但仍未能通过画布将svg转换为png。
    后备将用画布替换目标< img> 标记。用户可以通过点击右键来保存后者。
  • 一些注意事项:

    它在Safari 7中不起作用,也可能在其他过时的webkit浏览器中。这是一个奇怪的错误,因为它在本地主机上的工作方式类似于魅力,但不会在任何其他网络上(即使在我的家庭网络上,使用192.168.xxx)。

    IE 9& IE 10将无法​​将外部图像转换为数据URL,CORS问题。




/ /如何处理结果(数据URL或直接画布如果被污染)var callback = function(d,isTainted){if(!isTainted){$('#chartImg')[0] .src = d; } else $('#chartImg')[0] .parentNode.replaceChild(d,$('#chartImg')[0]);}; //外部图像的URL(必须是跨源兼容的)var extURL ='https://dl.dropboxusercontent.com/s/13dv8vzmrlcmla2/tex2.jpg';google.load('visualization','1',{packages:['corechart']})var encodeCall = getbase64URI.bind (this,extURL,callback); google.setOnLoadCallback(encodeCall); // Google Chart partfunction drawVisualizationDaily(imgUrl,callback,isTainted){var data = google.visualization.arrayToDataTable([['Daily','Sales'],[ ''星期四',4],['星期六',6],['星期六',6],['星期五',5],['星期三',3],['星期六',7] ',7]]); var chart = new google.visualization.ColumnChart(document.getElementById('visualization')); chart.draw(data,{title:Daily Sales,width:500,height:400,hAxis:{title:Daily}}); //链接到图表的svg元素var svgNode = chart.ea.querySelector('svg'); //为我们的图像创建一个符号var symbol = document.createElementNS('http://www.w3.org/2000/svg','symbol'); //使用< use>允许大小更改的svg包装器symbol.setAttributeNS(null,'viewBox','0,0,10,10'); symbol.setAttributeNS(null,'preserveAspectRatio','none'); symbol.id ='背景'; //和我们的编码图像的实际图像var img = document.createElementNS('http://www.w3.org/2000/svg','image'); img.setAttributeNS(null,'preserveAspectRatio','none'); img.setAttributeNS(null,'width','100%'); img.setAttributeNS(null,'height','100%'); img.setAttributeNS('http://www.w3.org/1999/xlink','href',imgUrl); symbol.appendChild(IMG); svgNode.appendChild(符号); var blueRects = $([fill ='#3366cc']); var max = blueRects.length - 1; blueRects.each(function(index,element){var svgimg = document.createElementNS('http://www.w3.org/2000/svg','use'); svgimg.setAttributeNS(null,'x',element .x.baseVal.value); svgimg.setAttributeNS(null,'y',element.y.baseVal.value); svgimg.setAttributeNS(null,'width',element.width.baseVal.value); svgimg.setAttributeNS( null,'height',element.height.baseVal.value); svgimg.setAttributeNS('http://www.w3.org/1999/xlink','href','#background'); svgNode.appendChild(svgimg ); if(index === max&!isTainted)//如果我们没有dataURL编码的图像,则不需要调用它//载入事件会更好,但它不会在IE中触发。 (svgNode,callback,isTainted),200);});}函数exportSVG(svgNode,callback,isTainted){var svgData =(new XMLSerializer())。serializeToString(svgNode); var img = new Image(); img.onload = function(){var canvas = document.createElement('canvas'); canvas.width = svgNode.getAttribute('width'); canvas.height = svgNode.getAttribute('height'); canvas.getContext('2d')。drawImage(this,0,0); var数据,isTainted;尝试{data = canvas.toDataURL(); } catch(e){data = canvas; isTainted = true; }回调(数据,isTainted); } img.src ='data:image / svg + xml; charset = utf8,'+ encodeURIComponent(svgData);} //将图片的url转换为base64数据的简单函数URLfunction getbase64URI(url,callback){var img = new Image(); img.crossOrigin =匿名; img.onload = function(){var c = document.createElement('canvas'); c.width = this.width; c.height = this.height; c.getContext('2d')。drawImage(this,0,0); var isTainted;尝试{c.toDataURL(); } catch(e){isTainted = true; } //如果画布受到污染,则返回url var output =(isTainted)? url:c.toDataURL(); drawVisualizationDaily(输出,回调,isTainted); }

svg {border: 1px纯黄色; } img {border:1px纯绿色; } canvas {border:1px solid red; }

< script src =http:// www .google.com / jsapi?.js>< / script>< script src =https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js>右键点击此图片以保存图片:< / script>< div id =visualization>< / div>< img id =chartImg/>


How can I get base64 with image inside of svg? Check this Fiddle that I got from another question. If you see the second graphic, its not generating the image that overlays the bar.

var chart = new google.visualization.ColumnChart(document.getElementById('chart_survey'));

$("[fill='#FFFFFF']").each(function( index, element ) {
    var svgimg = document.createElementNS('http://www.w3.org/2000/svg','image');
    svgimg.setAttributeNS(null,'x',element.x.baseVal.value);
    svgimg.setAttributeNS(null,'y',element.y.baseVal.value);
    svgimg.setAttributeNS(null,'width',element.width.baseVal.value);
    svgimg.setAttributeNS(null,'height',element.height.baseVal.value);
    svgimg.setAttributeNS(null,'preserveAspectRatio','none');
    svgimg.setAttributeNS('http://www.w3.org/1999/xlink','href', '${application.contextPath}/images/textura/patt.gif');
    $(element).parent().append(svgimg);
});

$('#test').val(chart.getImageURI())

解决方案

In order to save this svg to a png, which keeps the linked <image> then you'll have to encode each <image>'s href to a dataURL first.

Edit

I rewrote the original snippets (which can still be found in the edit history).

  • I changed the <image> tags to <use>. This results in a much smaller memory usage.

  • I also added a fallback for IE11, which accepts to encode the external image to data URL, but still fails to convert svg to png via canvas. The fallback will replace the destination <img>tag, with the canvas. The later can be saved by user with a right click.

  • A few caveats :
    It doesn't work in Safari 7, and maybe in other outdated webkit browsers. That's a strange bug, since it does work like a charm in localhost, but won't on any other network (even on my home network, using 192.168.xxx).
    IE 9 & IE 10 will fail to convert the external images to data URL, CORS problem.

// What to do with the result (either data URL or directly the canvas if tainted)
var callback = function(d, isTainted) {
  if (!isTainted) {
    $('#chartImg')[0].src = d;
  } else
    $('#chartImg')[0].parentNode.replaceChild(d, $('#chartImg')[0]);
};
// The url of the external image (must be cross-origin compliant)
var extURL = 'https://dl.dropboxusercontent.com/s/13dv8vzmrlcmla2/tex2.jpg';

google.load('visualization', '1', {
  packages: ['corechart']
})

var encodeCall = getbase64URI.bind(this, extURL, callback);
google.setOnLoadCallback(encodeCall);



// Google Chart part
function drawVisualizationDaily(imgUrl, callback, isTainted) {

  var data = google.visualization.arrayToDataTable([
    ['Daily', 'Sales'],
    ['Mon', 4],
    ['Tue', 6],
    ['Wed', 6],
    ['Thu', 5],
    ['Fri', 3],
    ['Sat', 7],
    ['Sun', 7]
  ]);

  var chart = new google.visualization.ColumnChart(document.getElementById('visualization'));

  chart.draw(data, {
    title: "Daily Sales",
    width: 500,
    height: 400,
    hAxis: {
      title: "Daily"
    }
  });

  // Link to chart's svg element
  var svgNode = chart.ea.querySelector('svg');
  // Create a symbol for our image
  var symbol = document.createElementNS('http://www.w3.org/2000/svg', 'symbol');
  // An svg wrapper to allow size changing with <use>
  symbol.setAttributeNS(null, 'viewBox', '0,0,10,10');
  symbol.setAttributeNS(null, 'preserveAspectRatio', 'none');
  symbol.id = 'background';
  // And the actual image, with our encoded image
  var img = document.createElementNS('http://www.w3.org/2000/svg', 'image');
  img.setAttributeNS(null, 'preserveAspectRatio', 'none');
  img.setAttributeNS(null, 'width', '100%');
  img.setAttributeNS(null, 'height', '100%');
  img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', imgUrl);

  symbol.appendChild(img);
  svgNode.appendChild(symbol);

  var blueRects = $("[fill='#3366cc']");
  var max = blueRects.length - 1;
  blueRects.each(function(index, element) {
    var svgimg = document.createElementNS('http://www.w3.org/2000/svg', 'use');
    svgimg.setAttributeNS(null, 'x', element.x.baseVal.value);
    svgimg.setAttributeNS(null, 'y', element.y.baseVal.value);
    svgimg.setAttributeNS(null, 'width', element.width.baseVal.value);
    svgimg.setAttributeNS(null, 'height', element.height.baseVal.value);
    svgimg.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#background');
    svgNode.appendChild(svgimg);

    if (index === max && !isTainted) // no need to call it if we don't have our dataURL encoded images
    // a load event would be better but it doesn't fire in IE ...
      setTimeout(exportSVG.bind(this, svgNode, callback, isTainted), 200);
  });
}

function exportSVG(svgNode, callback, isTainted) {

  var svgData = (new XMLSerializer()).serializeToString(svgNode);

  var img = new Image();
  img.onload = function() {
    var canvas = document.createElement('canvas');
    canvas.width = svgNode.getAttribute('width');
    canvas.height = svgNode.getAttribute('height');
    canvas.getContext('2d').drawImage(this, 0, 0);
    var data, isTainted;
    try {
      data = canvas.toDataURL();
    } catch (e) {
      data = canvas;
      isTainted = true;
    }
    callback(data, isTainted);
  }
  img.src = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(svgData);
}

// A simple function to convert an images's url to base64 data URL
function getbase64URI(url, callback) {
  var img = new Image();
  img.crossOrigin = "Anonymous";
  img.onload = function() {
    var c = document.createElement('canvas');
    c.width = this.width;
    c.height = this.height;
    c.getContext('2d').drawImage(this, 0, 0);
    var isTainted;
    try {
      c.toDataURL();
    } catch (e) {
      isTainted = true;
    }
    // if the canvas is tainted, return the url
    var output = (isTainted) ? url : c.toDataURL();
    drawVisualizationDaily(output, callback, isTainted);
  }
  img.src = url;
}

svg    { border: 1px solid yellow; }
img    { border: 1px solid green;  }
canvas { border: 1px solid red;    }

<script src="http://www.google.com/jsapi?.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="visualization"></div>
Right-click this image to save it:
<br>
<img id="chartImg" />

这篇关于如何在Google图表中获得带有svg内图像的png(base64)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆