You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HTML Canvas如何通过alpha蒙版图片为原图添加透明效果

Canvas黑白蒙版为原图添加透明效果实现

原有代码失效原因

代码无法实现预期效果是几个硬伤导致的:

  • 图片加载是异步行为,没有等待原图、蒙版都加载完成就执行像素处理逻辑,大概率拿到的是空画布数据
  • 画布、原图、蒙版三者尺寸没有做对齐,很容易出现内容错位、拉伸问题
  • 像素处理逻辑错误,左移8位的操作会直接覆盖原图内容,根本没有把蒙版的灰度值正确写入alpha通道
  • 加载跨域图片没有配置跨域属性,getImageData会直接触发浏览器安全限制被拦截

可直接运行的正确代码

替换原有逻辑即可生效:

const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

// 等待两张素材全部加载完成再执行处理
let loadedCount = 0;
const originImg = new Image();
const maskImg = new Image();
// 配置跨域避免Canvas安全限制
originImg.crossOrigin = maskImg.crossOrigin = "anonymous";
originImg.src = "https://i.sstatic.net/fj5mB.jpg";
maskImg.src = "https://i.sstatic.net/5lDgg.png";

const handleImgLoad = () => {
  loadedCount++;
  if (loadedCount < 2) return;

  // 主画布尺寸和原图保持一致
  canvas.width = originImg.width;
  canvas.height = originImg.height;

  // 第一步:先把原图绘制到主画布
  ctx.drawImage(originImg, 0, 0);
  const originImgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  const originPixels = originImgData.data;

  // 第二步:创建离屏画布绘制蒙版,尺寸和主画布对齐
  const maskCanvas = document.createElement("canvas");
  const maskCtx = maskCanvas.getContext("2d");
  maskCanvas.width = canvas.width;
  maskCanvas.height = canvas.height;
  maskCtx.drawImage(maskImg, 0, 0, canvas.width, canvas.height);
  const maskPixels = maskCtx.getImageData(0, 0, canvas.width, canvas.height).data;

  // 第三步:逐像素把蒙版灰度值写入原图对应位置的alpha通道
  for (let i = 0; i < originPixels.length; i += 4) {
    // 黑白蒙版R=G=B,直接取R通道值作为透明度值即可
    originPixels[i + 3] = maskPixels[i];
  }

  // 把处理完成的像素数据写回主画布
  ctx.putImageData(originImgData, 0, 0);
};

originImg.onload = maskImg.onload = handleImgLoad;

效果规则

  • 蒙版纯黑区域(R值为0):对应原图完全透明
  • 蒙版纯白区域(R值为255):对应原图完全不透明
  • 蒙版灰色区域:按灰度值等比映射透明度,过渡自然无硬边

内容的提问来源于stack exchange,提问作者Elviin Goomez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 08:27:23