我已使用css将背景图像添加到画布。
但是当使用canvas.toDataURL()将其转换为png时,它没有显示背景图像。
好像它没有解析css背景图片。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.914/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.914/styles/kendo.default.min.css">
<script src="http://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2016.3.914/js/kendo.all.min.js"></script>
</head>
<body>
<div id="invoices-grid"></div>
<script>
$(function() {
var d = [];
for (var i = 1; i <= 100; i++) {
d.push({Id: i, CustomerName: "CustomerName " + i});
}
$("#invoices-grid").kendoGrid({
dataSource: {
data: d,
schema: {
model: {
id: "Id",
fields: {
CustomerName: { type: "string" }
}
}
},
error: function(e) {
display_kendoui_grid_error(e);
// Cancel the changes
this.cancelChanges();
},
pageSize: 20,
//serverPaging: true,
//serverFiltering: true,
//serverSorting: true
},
columns: [
{
field: "CustomerName",
title: "gp.Invoice.Fields.CustomerName",
template: '#= CustomerName #'
},
{
field: "Id",
title: "Common.Edit",
width: 100,
template: '<a href="Edit/#=Id#">Common.Edit</a>'
},
],
pageable: {
refresh: true,
pageSizes: [5, 10, 20, 50]
},
editable: {
confirmation: false,
mode: "popup"
},
scrollable: false,
selectable: true,
change: function(e) {
}
});
});
</script>
</body>
</html>
答案 0 :(得分:1)
如评论中所述,background-image
不是画布上下文的一部分,因此无法通过任何画布的导出方法导出。
如果你想在画布上绘制这个图像,只需在绘制另一个图像之前绘制它。*主要的难点是重现CSS背景的不同选项。但在你的情况下,它很简单。
var svgString = new XMLSerializer().serializeToString(document.querySelector('svg'));
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var DOMURL = self.URL || self.webkitURL || self;
var svg = new Blob([svgString], {
type: "image/svg+xml"
});
var url = DOMURL.createObjectURL(svg);
var png = '';
var toLoad = 2;
var loaded = 0;
var background = new Image();
var svgImg = new Image();
// attach the event to both images
background.onload = svgImg.onload = function(){
// only when both has loaded
if(++loaded === toLoad){
// set the canvas size to the svg image's one
canvas.width = svgImg.width;
canvas.height = svgImg.height;
// draw the background image first
ctx.drawImage(background, (canvas.width/2)-(background.width/2), (canvas.height/2)-(background.height/2));
// then the svg image
ctx.drawImage(svgImg, 0, 0);
png = canvas.toDataURL("image/png");
document.querySelector('#chart').innerHTML = '<img src="' + png + '"/>';
// you want to revoke the svgImg ObjectURL, not the canvas dataURI
DOMURL.revokeObjectURL(svgImg.src);
}
}
svgImg.src = url;
// set it only if you're doing a cross origin request
// Object URL are not
background.crossOrigin = 'anonymous';
background.src = 'https://dl.dropboxusercontent.com/s/4e90e48s5vtmfbd/aaa.png'
svg{border: 1px solid red;}
canvas{border: 1px solid blue;}
img{border: 1px solid green;}
<svg width="120" height="120" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
<rect x="10" y="10" width="55" height="55" fill-opacity=".5"/>
</svg>
<canvas id="canvas"></canvas>
<p id="chart"></p>
*正如markE所说,如果您无法在之前绘制背景,您还可以将上下文的globalCompositeOperation
设置为destination-over
以便绘制<强>落后实际内容。
现在,这显然不是你问题的一部分,但是如果你试图将background-image
设置为你的svg节点,那么你应该能够在你的画布上绘制它,作为svg的一部分。
但由于HTMLImage(<img>
)元素无法从其加载的媒体加载任何外部资源,因此您必须先将图像转换为dataURI版本,然后将样式附加为svg的{{1 }},在svg元素内附加的style
元素中。
这是一个丑陋的例子,它将使用CSS定义的背景图像转换svg元素,并在画布上绘制。
不要使用它,这只是为了演示,但可能会破坏。此外,这只是针对FF,Chrome和Safari进行了快速测试。
<style>
function convertSVGWithBG(svg, callback) {
// this function is not be bullet proof, better if you know the urls in advance
// in case of multi-images
var imgsToLoad = getComputedStyle(svg).backgroundImage.split(',');
appendDocumentStylesTo(svg);
var toLoad = imgsToLoad.length,
loaded = 0,
// we need to keep it sorted
rules = [],
canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d');
imgsToLoad.forEach(function(s, i) {
var bgURL = parseURL(s),
bgImg = new Image();
bgImg.crossOrigin = 'anonymous';
var errored = false;
bgImg.onload = function() {
canvas.width = this.width;
canvas.height = this.height;
ctx.drawImage(this, 0, 0);
rules[i] = canvas.toDataURL();
if (++loaded === toLoad) {
onend();
}
bgImg.onerror = function() {
if (!errored) {
errored = true;
this.crossOrigin = null;
this.removeAttribute('crossorigin');
this.src = this.src;
} else {
console.warn('failed to load img at src ', this.src);
if (--toLoad === loaded) {
onend();
}
}
};
};
bgImg.src = bgURL;
function onend() {
var toLoad = rules.filter(function(r) {
return r;
}).length,
loaded = 0;
// wait for the dataURI version has loaded too
rules.forEach(function(url) {
var img = new Image();
img.onload = function() {
if (++loaded === toLoad) {
callback(svg);
}
};
img.src = url
});
// it has to be inline style, or appended in a <style> element directly in our svg element
var fullRule = 'url(' + rules.join('), url(') + ')';
svg.style.backgroundImage = fullRule;
}
});
function parseURL(str) {
// this is ugly and there should be a better way to do so (maybe regex)
var url = str.split('"')[1];
if (!url) {
url = str.split("'")[1];
}
if (!url) {
url = str.split('(')[1].split(')')[0];
}
return url;
}
}
function svgToCanvas(svg) {
var svgString = new XMLSerializer().serializeToString(svg);
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var DOMURL = self.URL || self.webkitURL || self;
var svg = new Blob([svgString], {
type: "image/svg+xml"
});
var url = DOMURL.createObjectURL(svg);
var svgImg = new Image();
svgImg.onload = function() {
canvas.width = svgImg.width;
canvas.height = svgImg.height;
ctx.drawImage(svgImg, 0, 0);
png = canvas.toDataURL("image/png");
document.querySelector('#chart').innerHTML = '<img src="' + png + '"/>';
DOMURL.revokeObjectURL(svgImg.src);
}
svgImg.src = url;
}
var svg = document.querySelector('svg');
convertSVGWithBG(svg, svgToCanvas);
// this is completely unstable and should never be used...
function appendDocumentStylesTo(element) {
var docStyleSheets = document.styleSheets;
var i = 0,
j, rules, r, key;
for (i; i < docStyleSheets.length; i++) {
rules = docStyleSheets[i].cssRules;
for (j = 0; j < rules.length; j++) {
r = rules[j];
if (element.matches(r.selectorText)) {
if (r.style) {
for (k = 0; k < r.style.length; k++) {
key = r.style[k];
// ugly hack for Safari
if (key.indexOf('repeat') > -1) {
key = 'background-repeat';
}
element.style[key] = r.style[key];
}
}
}
}
}
}
canvas {
border: 1px solid blue;
}
img {
border: 1px solid green;
}
svg {
background-image: url(https://dl.dropboxusercontent.com/s/rumlhyme6s5f8pt/ABC.png), url(https://dl.dropboxusercontent.com/s/4e90e48s5vtmfbd/aaa.png);
background-position: 50%;
background-repeat: no-repeat;
}
答案 1 :(得分:0)
<flow name="testdbFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/test" doc:name="HTTP"/>
<set-payload value="{"1234567890123456":"Y","1234567890123457":"Y"}" mimeType="application/json" doc:name="Set Payload"/>
<dw:transform-message doc:name="Transform Message">
<dw:input-payload />
<dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
(payload mapObject {
x: {
key : $$,
value : $
}
}).*x]]>
</dw:set-payload>
</dw:transform-message>
<json:json-to-object-transformer returnClass="java.util.List" doc:name="JSON to Object"/>
<db:update config-ref="MySQL_Configuration" bulkMode="true" doc:name="Database">
<db:dynamic-query><![CDATA[UPDATE cwg_ws_data SET SyncFlag = '#[payload.value]' WHERE IMEI = '#[payload.key]']]></db:dynamic-query>
</db:update>
</flow>