尝试对<img>
标记应用模糊效果时,画布上不显示任何内容。
我正在<img>
传递<foreignObject>
标记,以便应用模糊效果。
这种技术适用于文本,但不适用于<img>
。
这是我的代码。
var canvas = document.getElementById('mycanvas');
var ctx = canvas.getContext('2d');
var data = '<svg xmlns="http://www.w3.org/2000/svg" width="700" height="350">'+
' <foreignObject width="100%" height="100%">'+
' <div xmlns="http://www.w3.org/1999/xhtml" style="font-size:40px">'+
//start code
' <div id="custom_image_box" class="col-xs-12 edit_div" style="background-color: rgb(255, 255, 255);">'+
' <div id="added_background_0" class="ui-widget-content draggable resizable ui-draggable ui-resizable ui-resizable-autohide" style="position: absolute; z-index: 0; -webkit-filter: blur(2px);">'+
' <img id="image_0" class="image_resize" src="http://localhost/image_designer/htdocs/assets/upload_image/1450334949.jpg" style=" width: 100%; height: 100%;">'+
' <div class="ui-resizable-handle ui-resizable-nw" id="nwgrip" "="" style="display: none;">'+
' </div>'+
' <div class="ui-resizable-handle ui-resizable-ne" id="negrip" style="display: none;">'+
' </div>'+
' <div class="ui-resizable-handle ui-resizable-sw" id="swgrip" style="display: none;">'+
' </div>'+
' <div class="ui-resizable-handle ui-resizable-se" id="segrip" style="display: none;">'+
' </div>'+
' </div>'+
' </div>'+
//end code
' </div>'+
' </foreignObject>'+
'</svg>';
var DOMURL = window.URL || window.webkitURL || window;
var img = new Image();
var svg = new Blob([data], {
type: 'image/svg+xml; charset=utf-8'
});
var url = DOMURL.createObjectURL(svg);
img.onload = function() {
ctx.drawImage(img, 0, 0);
DOMURL.revokeObjectURL(url);
}
img.src = url;
<canvas id="mycanvas" width="700" height="300"></canvas>
答案 0 :(得分:0)
首先,
为了正确显示<foreignObject>
标记中的<img>
,您必须使用完美编写的HTML。您忘记关闭<img/>
标记,因此未显示任何内容。 "=""
div上还有一些奇怪的#nwgrip
属性
要避免此类问题,最好的方法是使用DOM,并调用new XMLSerializer.serializeToString(yourDOMElement)
。这样,浏览器就已经完成了解析,并且您的标记将被清理。
清理代码,显示空图像,模糊:
var canvas = document.getElementById('mycanvas');
var ctx = canvas.getContext('2d');
var data = '<svg xmlns="http://www.w3.org/2000/svg" width="700" height="350">' +
'<foreignObject width="100%" height="100%">' +
'<div xmlns="http://www.w3.org/1999/xhtml" style="font-size:40px">' +
'<div style="background-color: rgb(255, 255, 255);">' +
'<div style="position: absolute; z-index: 0; -webkit-filter: blur(2px); filter: blur(2px);">' +
// added some text to show the blur effect does work
'some text'+
'<img src="https://dl.dropboxusercontent.com/s/1alt1303g9zpemd/UFBxY.png" style="width: 100%; height: 100%;"/>' +
'</div>' +
'</div>' +
'</div>' +
'</foreignObject>' +
'</svg>';
var DOMURL = window.URL || window.webkitURL || window;
var img = new Image();
var svg = new Blob([data], {
type: 'image/svg+xml; charset=utf-8'
});
var url = DOMURL.createObjectURL(svg);
img.onload = function() {
ctx.drawImage(img, 0, 0);
DOMURL.revokeObjectURL(url);
}
img.src = url;
<canvas id="mycanvas" width="700" height="350"></canvas>
其次,
您无法从<img>
标记加载任何外部数据。因此,在您的情况下,这意味着您不想加载要显示的<img>
资源。
一个解决方案,首先将图像转换为dataURL版本,然后将img标记的src
设置为所需的dataURL:
var srcToDataURL = function(src, callback) {
var ctx = document.createElement('canvas').getContext('2d');
var img = new Image();
img.crossOrigin = "anonymous";
img.onload = function() {
ctx.canvas.width = this.width;
ctx.canvas.height = this.height;
ctx.drawImage(this, 0, 0);
callback(ctx.canvas.toDataURL());
}
img.src = src;
};
var src = "https://dl.dropboxusercontent.com/s/1alt1303g9zpemd/UFBxY.png";
srcToDataURL(src, function(imgData) {
var canvas = document.getElementById('mycanvas');
var ctx = canvas.getContext('2d');
var data = '<svg xmlns="http://www.w3.org/2000/svg" width="700" height="350">' +
'<foreignObject width="100%" height="100%">' +
'<div xmlns="http://www.w3.org/1999/xhtml" style="font-size:40px">' +
'<div style="background-color: rgb(255, 255, 255);">' +
'<div style="position: absolute; z-index: 0; -webkit-filter: blur(2px); filter: blur(2px);">' +
'<img src="'+ imgData + '" style="width: 100%; height: 100%;"/>' +
'</div>' +
'</div>' +
'</div>' +
'</foreignObject>' +
'</svg>';
var DOMURL = window.URL || window.webkitURL || window;
var img = new Image();
var svg = new Blob([data], {
type: 'image/svg+xml; charset=utf-8'
});
var url = DOMURL.createObjectURL(svg);
img.onload = function() {
ctx.drawImage(img, 0, 0);
DOMURL.revokeObjectURL(url);
}
img.src = url;
});
<canvas id="mycanvas" width="700" height="350"></canvas>
<强>第三,强>
IE&lt; Edge和Safari 9(最新版)不支持在画布上绘制<foreignObject>
,并且会污染它。 html2canvas将无法再捕捉您的画布。
如果您必须支持这些浏览器,更好的方法是使用像StackBlur这样的库直接将图像模糊到画布上。
作为旁注,您不需要使用Blob构造函数将svg附加到画布上,dataURI方式适用于更多浏览器,并且知道的错误较少:
var srcToDataURL = function(src, callback) {
var ctx = document.createElement('canvas').getContext('2d');
var img = new Image();
img.crossOrigin = "anonymous";
img.onload = function() {
ctx.canvas.width = this.width;
ctx.canvas.height = this.height;
ctx.drawImage(this, 0, 0);
callback(ctx.canvas.toDataURL());
}
img.src = src;
};
var src = "https://dl.dropboxusercontent.com/s/1alt1303g9zpemd/UFBxY.png";
srcToDataURL(src, function(imgData) {
var canvas = document.getElementById('mycanvas');
var ctx = canvas.getContext('2d');
var data = '<svg xmlns="http://www.w3.org/2000/svg" width="700" height="350">' +
'<foreignObject width="100%" height="100%">' +
'<div xmlns="http://www.w3.org/1999/xhtml" style="font-size:40px">' +
'<div style="background-color: rgb(255, 255, 255);">' +
'<div style="position: absolute; z-index: 0; -webkit-filter: blur(2px); filter: blur(2px);">' +
'<img src="'+ imgData + '" style="width: 100%; height: 100%;"/>' +
'</div>' +
'</div>' +
'</div>' +
'</foreignObject>' +
'</svg>';
var img = new Image();
var url = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(data);
img.onload = function() {
ctx.drawImage(img, 0, 0);
}
img.src = url;
});
<canvas id="mycanvas" width="700" height="350"></canvas>