如何在Google图表中获得带有svg内图像的png(base64)? [英] How can I get png(base64) with images inside of svg in Google Charts?
问题描述
如何在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。 -
一些注意事项:
它在Safari 7中不起作用,也可能在其他过时的webkit浏览器中。这是一个奇怪的错误,因为它在本地主机上的工作方式类似于魅力,但不会在任何其他网络上(即使在我的家庭网络上,使用192.168.xxx)。
IE 9& IE 10将无法将外部图像转换为数据URL,CORS问题。
后备将用画布替换目标
< img>
标记。用户可以通过点击右键来保存后者。
/ /如何处理结果(数据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屋!