Angular客户端图片压缩使用drawImage输出全黑1KB图片问题求助
问题根因排查
- 图片未完成加载就执行绘制:
Image对象加载资源是异步操作,给img1.src赋值后直接调用drawImage,此时图片还未加载完成,canvas绘制的是空内容,就会生成全黑的空白图片。 - canvas未设置宽高:默认创建的canvas画布尺寸为300*150,你代码中直接从坐标(400,400)的位置开始绘制图片,绘制区域完全超出了画布可视范围,自然看不到有效内容。
- drawImage参数使用错误:
drawImage第一个参数要求是已加载完成的Image/Canvas/Video对象,不能直接传入File文件对象,这也是对应代码行抛异常的直接原因。
修正后的代码
selectImage(event: any){ if(event.target.files.length>0){ const file = event.target.files[0]; this.reader_img(file); } } reader_img(file:File){ const reader = new FileReader(); reader.readAsDataURL(file); // 改用箭头函数避免this指向问题 reader.onload = () => { if(!reader.result){ throw new Error(`error1`) } const img1 = new Image(); // 先绑定加载完成事件再赋值资源地址,兼容低版本浏览器 img1.onload = () => { // 自定义压缩后的图片尺寸,这里示例按等比缩放,宽设为400,高自适应 const targetWidth = 400; const targetHeight = img1.height * (targetWidth / img1.width); // 给canvas设置对应宽高 const cvs = document.createElement('canvas'); cvs.width = targetWidth; cvs.height = targetHeight; const ctx = cvs.getContext("2d"); if (!ctx) { throw new Error(`error2`); } // 从画布左上角(0,0)开始绘制,铺满整个画布 ctx.drawImage(img1, 0, 0, targetWidth, targetHeight); // 输出base64,第二个参数0.8是图片质量,可根据压缩需求调整0-1之间的数值 console.log(cvs.toDataURL('image/jpeg', 0.8)); } img1.src = reader.result.toString(); // 图片加载失败捕获 img1.onerror = (err) => { console.log('图片加载失败:', err) } }; reader.onerror = (error) => { console.log('文件读取失败: ', error); }; }
额外注意事项
- 如果需要导出透明背景的图片,将
toDataURL的第一个参数改为image/png即可,png格式不支持质量参数调整。 - 如果后续需要处理线上跨域图片,需要给图片对象设置
img1.crossOrigin = 'anonymous',同时要求图片资源服务器配置了跨域许可,否则canvas会被污染无法导出内容。
内容的提问来源于stack exchange,提问作者vignesh p
相关产品推荐
相关产品推荐

