如何使用画布应用 alpha 图层蒙版以使某些图像透明

2024-04-27

有人可以帮我解决这个问题吗? 我想使用画布应用 alpha 图层蒙版以使某些图像透明。

多谢。

var redImageData = redCanvas.getContext("2d").getImageData(0, 0, 200, 200); //overlay
    var ImageData = imageCanvas.getContext("2d").getImageData(0, 0, 200, 200);

var px = redImageData.data;
var px2 = ImageData.data;
for(var i = 0; i < px.length; i += 4) {
     if(px[i + 0] == 0 && px[i + 1] == 0 && px[i+2] == 0){
         px[i + 3] = 0;
     } else {
         px[i + 0] = px2[i + 0];
         px[i + 1] = px2[i + 1];
         px[i + 2] = px2[i + 2];
         px[i + 3] = px2[i + 3];
     }
}
ctx.imageSmoothingEnabled = true;
ctx.putImageData(redImageData, 0, 0);

阿尔法面具过度https://i.stack.imgur.com/zCzOf.png https://i.stack.imgur.com/zCzOf.png


链接的图像实际上并不是 alpha mask,而是matte图像。不同之处在于哑光图像代表什么would是一个 alpha 通道,但将其显示为 RGB(或灰度)分量。它实际上没有 alpha 通道。遮罩图像在视频合成软件中很常见,但在网络上不太有用。

Canvas 或其使用的 Porter-Duff 方法不直接支持遮罩图像,因此必须首先将它们转换为实际的 Alpha 通道。为此,您必须迭代每个像素并将其中一个分量值(从红色、绿色或蓝色 - 无论是哪一个)移动到 alpha 通道中。

完成后,您可以使用画布对象,该对象现在具有正确的 alpha 通道和仅使用 alpha 信息的复合操作(混合模式是不同的章节)。

更好的方法当然是提供具有适当 Alpha 通道的 PNG 图像。但无论如何,为了表明也可以使用遮罩图像,尽管效率不高,我们可以执行以下操作:

将遮罩图像转换为 Alpha 通道

第一步:此代码部分展示了如何有效地执行将遮罩图像转换为 Alpha 通道的预处理步骤。正如已经提到的,最终的颜色对于主要合成步骤并不重要,因为它只会使用 alpha 通道。

只需在尝试使用图像之前确保图像已正确加载,方法是使用图像的onload回调或在所有内容加载后运行脚本。

此代码将简单地将使用像素的完整 32 位值(为了提高效率)的组件(在本例中为蓝色)转移到 alpha 通道中,这使得图像看起来青色,但具有适当的 alpha,正如您在橙色背景中看到的那样显示出来(不过大部分代码是用来处理加载和设置的)。

window.onload = function() {

  // at this stage the image has loaded:
  var img = document.getElementById("img");
  var canvas = document.getElementById("c");
  var ctx = canvas.getContext("2d");

  // - setup canvas to match image
  canvas.width = img.naturalWidth;
  canvas.height = img.naturalHeight;

  // - draw image
  ctx.drawImage(img, 0, 0);

  // CONV. STEP: move a component channel to alpha-channel
  var idata = ctx.getImageData(0, 0, canvas.width, canvas.height);
  var data32 = new Uint32Array(idata.data.buffer);
  var i = 0, len = data32.length;
  
  while(i < len) {
    data32[i] = data32[i++] << 8; // shift blue channel into alpha (little-endian)
  }
  
  // update canvas
  ctx.putImageData(idata, 0, 0);      
};
body {background: #f72; font-size:44px; color:rgba(0,0,0,0.5)}
<img id="img" crossorigin="anonymous" src="https://i.imgur.com/QRGYuWg.png"> ► 
<canvas id="c"></canvas>

合成

第二部分接下来将涉及使用新的 Alpha 通道进行合成。

在这种情况下,哑光图像的黑色变得完全透明,而白色变得完全不透明。您可以在转换步骤中反转此操作,但只要您知道遮罩图像的外观,它就不会真正遮罩。

为了替换内部内容,我们使用合成模式source-in。这将根据 alpha 值替换内容,同时保持 alpha 通道不变。

首先使用相同的模式处理内部部分允许我们在绘制框架之前对内容做其他事情(想想小插图、阴影等)。

作为最后一步,我们使用合成模式填充透明区域,即框架本身destination-over它用绘制到画布的内容替换了更透明的区域(从概念上讲,它绘制在现有内容的“后面”)。

下面的代码使用简单的彩色框 - 只需将它们替换为您想要绘制的任何内容即可。

window.onload = function() {
  var img = document.getElementById("img");
  var canvas = document.getElementById("c");
  var ctx = canvas.getContext("2d");
  canvas.width = img.naturalWidth;
  canvas.height = img.naturalHeight;
  ctx.drawImage(img, 0, 0);

  var idata = ctx.getImageData(0, 0, canvas.width, canvas.height);
  var data32 = new Uint32Array(idata.data.buffer);
  var i = 0, len = data32.length;
  while(i < len) data32[i] = data32[i++] << 8;
  ctx.putImageData(idata, 0, 0);
  
  // COMP. STEPS: use the mask with composite operation. Since our frame
  // is black (= transparent as alpha) we can use the following mode:
  ctx.globalCompositeOperation = "source-in";
  
  // draw something, here a blue box, replace with whatever you want
  ctx.fillStyle = "blue";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  
  // to fill the frame area, still transparent, use this mode:
  ctx.globalCompositeOperation = "destination-over";
  ctx.fillStyle = "yellow";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
};
body {background: #f72; font-size:44px; color:rgba(0,0,0,0.5)}
<img id="img" crossorigin="anonymous" src="https://i.imgur.com/QRGYuWg.png"> ► 
<canvas id="c"></canvas>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用画布应用 alpha 图层蒙版以使某些图像透明 的相关文章

随机推荐

  • 为什么我的音频不倒带?

    我在 Javascript 中倒带音频时遇到了一些问题 我基本上有一个倒计时 当倒计时接近结束时 每秒都会发出蜂鸣声 我尝试使用 var bip new Audio http www soundjay com button beep 7 w
  • PL/SQL 打印存储过程返回的引用游标

    如何从存储过程 OUT 变量 返回的引用游标中获取数据并将结果行打印到 SQL PLUS 中的 STDOUT ORACLE存储过程 PROCEDURE GetGrantListByPI p firstname IN VARCHAR2 p l
  • 为什么我的 sed 命令在使用变量时失败?

    使用 bash 我尝试插入日期变量并搜索该日期的日志文件 然后将输出发送到文件 如果我像这样对日期进行硬编码 它会起作用 sed n Nov 22 2010 p file gt log file 但如果我这样做就会失败 date Nov 2
  • MVC 在视图之间传输数据

    我刚刚开始学习 MVC 并试图了解它是如何工作的 我不想将用户发送到所有编辑 插入和列表操作的不同视图 在我的示例应用程序中 视图包含项目列表 列表下方有一个带有操作 Controller Create 的表单 用于插入新项目 但没有创建视
  • 在cocos2d中添加UIViewController

    我想在 cocos2d 项目中显示 UIViewController 所以我在我的 CCLayer 类中执行此操作 void displayMainMenu CGSize screenSize CCDirector sharedDirect
  • RuntimeException 以外的异常

    Java中除了RuntimeException之外还有其他可能发生的异常吗 谢谢 是的 有Three kinds 检查异常 编译器会让您知道何时可能会抛出它们 最有可能是由于环境中的故障 如果程序可以用它们做某事 则应该捕获它们 否则最好让
  • Oracle:SQL 选择带时间戳的日期

    我有以下数据 SQL gt select from booking session BK ID BK DATE 1 18 MAR 12 10 00 00 000000 2 18 MAR 12 10 25 00 000000 3 18 MAR
  • 在哪里可以找到 Python 的 win32api 模块? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我需要下载 Python 2 7 的它 但似乎找不到它 还有一个新选项 通过 pip 获取 有一个包p
  • 如何将灰度图像转换为像素值列表?

    我正在尝试创建一个 python 程序 它采用灰度 24 24 像素图像文件 我尚未决定类型 因此欢迎提出建议 并将其转换为从 0 白色 到 255 的像素值列表 黑色的 我计划使用这个数组来创建一个MNIST http yann lecu
  • 如何在 Java (NetBeans) 中将禁用按钮的文本颜色更改为黑色?

    我正在使用 NetBeans 用 Ja va 开发 GUI 我喜欢将禁用按钮的文本颜色更改为黑色 以下命令在组合框上运行良好 UIManager getDefaults put ComboBox disabledForeground Col
  • 为什么View Source会发出新的HTTP请求?

    我注意到 Firefox 和 Chrome 都发布了一个新的HTTP请求当你view the source对于您已经加载的网页 当页面本身加载缓慢或根本无法加载时 这尤其令人烦恼 这是为什么 他们不会已经缓存了最初接收的页面的现有源吗 是否
  • Windows Phone 7 可以实现 ping 吗?

    为了了解 WP7 中的网络功能 我将构建一个简单的 ping 应用程序 该应用程序将显示对某个主机的 ICMP ping 请求的结果 然而 不仅System Net NetworkInformation Ping班级不见了 System N
  • Golang导入包错误

    go 5 2 在以下任一位置找不到包 github com googollee go socket io usr local go src github com googollee go socket io 来自 GOROOT Users
  • Python - 使用“astype”进行 pandas 列类型转换不起作用

    这是 DataFrame 的前 5 行 格式很差 但您可以看到其中大多数值都可以转换为数字 df head ID Overall Acceleration Aggression Agility Balance Ball control Co
  • 以多列显示数据

    您好 我需要从 mySQL 表构建一个包含四列的表 这是我现在拥有的
  • 最后执行一定的规则

    我目前正在编写一个 Snakefile 它进行了大量的对齐后质量控制 CollectInsertSizeMetics CollectAlignmentSummaryMetrics CollectGcBiasMetrics 在 Snakefi
  • html 文件中的脚本标记中的 VSCode 中缺少建议

    使用时 stylevscode 中的 javascript 方法
  • Apache 下的子域代理到 Tomcat

    在使用 AJP 代理 Tomcat 时 我在为 Windows 计算机创建子域时遇到问题 这是我的 httpd conf 文件中的内容
  • 针对 Mahout 推荐器使用多个加权数据模型

    我有一个基于用户相似性的布尔偏好推荐器 我的数据集本质上包含关系 其中 ItemId 是用户决定阅读的文章 我想添加第二个数据模型 其中 ItemId 是对特定主题的订阅 我能想到的唯一方法是将两者合并在一起 偏移订阅 ID 这样它们就不会
  • 如何使用画布应用 alpha 图层蒙版以使某些图像透明

    有人可以帮我解决这个问题吗 我想使用画布应用 alpha 图层蒙版以使某些图像透明 多谢 var redImageData redCanvas getContext 2d getImageData 0 0 200 200 overlay v