Javascript canvas toDataURL未返回完整图像
我正在构建一个jQuery插件,用于对图像进行水印处理(是的,我很清楚javascript/html5水印系统的诸多缺点,但现在就忽略它了。)每个图像的基本方法是:Javascript canvas toDataURL未返回完整图像,javascript,jquery,html,canvas,Javascript,Jquery,Html,Canvas,我正在构建一个jQuery插件,用于对图像进行水印处理(是的,我很清楚javascript/html5水印系统的诸多缺点,但现在就忽略它了。)每个图像的基本方法是: 将图像粘贴到画布的背景上 在上面添加水印图像的数据, 将原始图像的src替换为画布的src(现在包含水印)。 现在,如果我将图像元素替换为画布本身,它似乎可以正常工作。。所有元素都显示在画布上。但是当我得到画布的dataURL时,除了最后一张画在画布上的图像之外,其他所有的东西都会出现。我甚至不介意,除了这个插件还需要替换到图像
- 将图像粘贴到画布的背景上
- 在上面添加水印图像的数据,
- 将原始图像的src替换为画布的src(现在包含水印)。
(function($){
$.fn.extend({
cmark: function(options) {
var defaults = {
type: 'image',
content: 'watermark.png',
filter: 'darker',
scale:300,
box: {
top : 0.5,
left : 0.5,
width : 0.75,
height : 0.75,
bgcolor : '#000000',
bgopacity : 0.5,
fgopacity : 1
},
callback_unsupported: function(obj){
return obj;
}
}
var getScale = function(w, h, scale){
ratio = Math.min(scale/w, scale/h);
scalew = Math.round(ratio*w);
scaleh = Math.round(ratio*h);
return [scalew,scaleh];
}
var options = $.extend(defaults, options);
return this.each(function() {
obj = $(this);
canvas = document.createElement('canvas');
if(!window.HTMLCanvasElement){
return options.callback_unsupported(obj);
}
/* if selecting for images, reset the images. Otherwise,
we're replacing link hrefs with data urls. */
if(obj.attr('src')){
target_img = obj.attr('src');
}
else if (obj.attr('href')){
target_img = obj.attr('href');
}
// get the filetype, make sure it's an image. If it is, get a mimetype. If not, return.
ftype = target_img.substring(target_img.lastIndexOf(".")+1).toLowerCase();
canvasbg = new Image();
canvasbg.onload = function(){
iw = canvasbg.width;
ih = canvasbg.height;
scale = getScale(iw, ih, options.scale);
iw = scale[0];
ih = scale[1];
canvas.setAttribute('width', iw);
canvas.setAttribute('height', ih);
ctx = canvas.getContext('2d');
/* define the box as a set of dimensions relative to the size of the image (percentages) */
bw = Math.round(iw * options.box.width);
bh = Math.round(ih * options.box.height);
// for now the box will only ever be centered.
bx = Math.round((iw * options.box.top) - (bw/2));
by = Math.round(ih * options.box.left - (bh/2));
/* draw the box unless the opacity is 0 */
if(options.box.bgopacity > 0){
ctx.fillStyle = options.box.bgcolor;
ctx.globalAlpha = options.box.bgopacity;
ctx.fillRect(bx, by, bw, bh);
}
wm = new Image();
wm.onload = function(){
ww = wm.width;
wh = wm.height;
scalar = Math.max(bw, bh); // scale to within the box dimensions
scale = getScale(ww, wh, scalar);
ww = scale[0];
wh = scale[1];
ctx.globalCompositeOperation = options.filter;
ctx.drawImage(wm, bx, by, ww, wh);
}
wm.src = options.content;
ctx.drawImage(canvasbg, 0, 0, iw, ih);
obj.replaceWith(canvas);
$('body').append('<img src="'+canvas.toDataURL()+'">');
//obj.attr('src', canvas.toDataURL());
}
canvasbg.src = target_img;
});
}
})
})(jQuery);
(函数($){
$.fn.extend({
cmark:功能(选项){
var默认值={
键入:“图像”,
内容:“水印.png”,
过滤器:“较暗”,
比例:300,
方框:{
排名:0.5,
左:0.5,
宽度:0.75,
身高:0.75,
bgcolor:“#000000”,
不透明度:0.5,
不透明度:1
},
不支持的回调函数:函数(obj){
返回obj;
}
}
var getScale=函数(w、h、scale){
比率=数学最小值(标度/w,标度/h);
scalew=数学四舍五入(比率*w);
scaleh=数学四舍五入(比率*h);
返回[scalew,scaleh];
}
var options=$.extend(默认值,选项);
返回此值。每个(函数(){
obj=$(本);
canvas=document.createElement('canvas');
如果(!window.htmlcanvaseElement){
返回选项。不支持回调(obj);
}
/*如果选择图像,请重置图像。否则,
我们正在用数据URL替换链接HREF*/
if(对象属性('src')){
target_img=obj.attr('src');
}
else if(obj.attr('href')){
target_img=obj.attr('href');
}
//获取文件类型,确保它是映像。如果是,则获取mimetype。如果不是,则返回。
ftype=target\u img.substring(target\u img.lastIndexOf(“.”+1).toLowerCase();
canvasbg=新图像();
canvasbg.onload=函数(){
iw=画布bg.width;
ih=画布高度;
scale=getScale(iw、ih、options.scale);
iw=标度[0];
ih=标度[1];
canvas.setAttribute('width',iw);
canvas.setAttribute('height',ih);
ctx=canvas.getContext('2d');
/*将框定义为相对于图像大小的一组尺寸(百分比)*/
bw=数学圆(iw*options.box.width);
bh=数学圆(ih*选项框高度);
//现在,盒子将永远不会居中。
bx=Math.round((iw*options.box.top)-(bw/2));
by=数学圆(ih*options.box.left-(bh/2));
/*除非不透明度为0,否则绘制长方体*/
如果(options.box.bg不透明度>0){
ctx.fillStyle=options.box.bgcolor;
ctx.globalAlpha=options.box.bgopacity;
ctx.fillRect(bx、by、bw、bh);
}
wm=新图像();
wm.onload=函数(){
ww=wm.width;
wh=wm.height;
scalar=Math.max(bw,bh);//缩放到框内尺寸
scale=getScale(ww、wh、标量);
ww=标度[0];
wh=刻度[1];
ctx.globalCompositeOperation=options.filter;
ctx.drawImage(wm、bx、by、ww、wh);
}
wm.src=options.content;
ctx.drawImage(canvasbg,0,0,iw,ih);
对象替换为(画布);
$('body')。追加('');
//obj.attr('src',canvas.toDataURL());
}
canvasbg.src=target\u img;
});
}
})
})(jQuery);
我添加了一行,将带有数据url的图像直接转储到页面上进行测试,这就是我看到的。。。左边是canvas元素,右边是带有数据url的图像:
是的,这已经让我难堪了好几天了。我可能错过了一些非常明显的东西,但我看不到
。。。已编辑,因为示例不再联机。对不起 首先,不要为标记构建那么大的字符串缓冲区
var img = new Image();
img.src = canvas.toDataURL();
$('body').append(img);
或者,如果您愿意:
$('body').append($('<img>').attr('src', canvas.toDataURL()))
$('body')。追加($('body')
第二,在绘制水印之前,您将获得画布的dataURL。绘制发生在wm.onload
回调函数中,该函数在加载水印时发生。在canvasbg.onload
触发后,才会触发,这就是您获取dataURL的地方
因此,在wm.onload
回调结束时,将图像附加到代码中,您应该会很好。如果您在某个地方主持了一个“工作”示例(显示您的问题),您可能会得到更多帮助,例如,您肯定走在正确的轨道上:我在OP的示例document.getE上运行了以下行