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

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

问题描述

如何在 svg 中获取带有图像的 base64?检查我从另一个问题中得到的 Fiddle.如果您看到第二个图形,则它不会生成覆盖该条的图像.

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())

推荐答案

为了将此 svg 保存为 png,从而保持链接的 然后您必须对每个href 首先指向 dataURL.

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.

我重写了原始片段(仍然可以在编辑历史记录中找到).

  • 我将 标签更改为 .这会导致更少的内存使用.

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

我还为 IE11 添加了一个后备,它接受将外部图像编码为数据 URL,但仍然无法通过画布将 svg 转换为 png.回退将用画布替换目标 标签.用户可以通过右键单击保存后者.

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.

一些注意事项:
它在 Safari 7 和其他过时的 webkit 浏览器中不起作用.这是一个奇怪的错误,因为它在本地主机中确实像魅力一样工作,但不会在任何其他网络上(即使在我的家庭网络上,使用 192.168.xxx).
IE 9 &IE 10 将无法将外部图像转换为数据 URL,CORS 问题.

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 Charts 中使用 svg 内的图像获取 png(base64)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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