Canvas添加PNG图片后无法显示,仅显示空白屏幕如何解决?
代码问题排查与修复
核心问题1:合成模式导致图片被背景遮挡
你设置了context.globalCompositeOperation = 'destination-over',这个属性的作用是新绘制的内容会放在已有内容的下方。你先绘制了白色背景,之后再画图片,图片就被白色背景完全盖住了。
解决方法:
- 直接去掉这个合成模式设置(默认是
source-over,新内容会在旧内容上方); - 或者调整绘制顺序:先画图片,再用
destination-over模式填充白色背景。
核心问题2:无效的Base64图片数据
你传入的Base64字符串里包含空格和注释//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==,Base64编码不允许有空格和非编码字符,这会导致图片加载失败。
修复后的有效Base64应该是:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4/8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==
其他潜在问题
- 图片加载失败无错误处理:
drawImages函数里只处理了onload,没加onerror,如果图片加载失败,Promise不会reject,会导致await一直挂起。需要补充:
img.onerror = () => reject(new Error('图片加载失败'));
- saveAs函数的href错误:直接把blob赋值给
a.href无效,需要用URL.createObjectURL(blob)生成可访问的链接,同时用完后要释放内存:
const saveAs = (blob, name) => { const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = name; a.click(); URL.revokeObjectURL(a.href); // 释放内存 a.remove(); }
修复后的完整代码
const saveAs = (blob, name) => { const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = name; a.click(); URL.revokeObjectURL(a.href); a.remove(); } const drawImages = (context, image) => new Promise((resolve, reject) => { const img = new Image(); img.onload = () => { context.drawImage(img, 0, 0); resolve('resolved'); } img.onerror = () => reject(new Error('图片加载失败')); img.src = image; }) const downloadCanvas = async() => { const canvas = document.createElement('canvas'); canvas.width = 8000; canvas.height = 8000; const context = canvas.getContext('2d'); // 去掉错误的合成模式,使用默认的source-over context.fillStyle = 'white'; context.fillRect(0, 0, canvas.width, canvas.height); // 使用修复后的Base64 await drawImages(context, `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4/8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==`); canvas.toBlob((blob) => saveAs(blob, 'name.png')); } downloadCanvas()
内容的提问来源于stack exchange,提问作者dropSh0t
相关产品推荐
相关产品推荐

