如何使用画布应用 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 图层蒙版以使某些图像透明 的相关文章

  • 内容脚本中的 Firefox SDK 访问首选项

    About 我正在使用 Firefox Add on SDK 开发 Firefox Add on 该附加组件将是特定于站点的 并将根据用户偏好隐藏某些元素 几年前我已经制作了这个附加组件 但使用新的 SDK 后 事情的工作方式有点不同 Co
  • 如何从字符串中删除除字母、数字、空格、感叹号和问号之外的所有内容?

    如何删除除以下内容之外的所有内容 字符串中的字母 数字 空格 感叹号 问号 该方法支持国际语言 UTF 8 非常重要 您可以使用正则表达式 myString replace w s g 这将替换除单词字符 空格 感叹号或问题之外的所有内容
  • Javascript/jQuery 变量未给出预期值

    和我之前的其他人一样 我也在 Javascript 的范围内苦苦挣扎 那并试图阅读该死的东西 我已经检查了关于这个问题的一些先前的线程 但我似乎无法让它们正确地应用于我的问题 在下面的示例中 我想操纵中的值tagsArr数组 一旦数组已完全
  • 添加 Javascript 按钮来更改 iframe 的内容

    我正在尝试创建此页面 其中有一个 Iframe 并且我想添加一个按钮来显示 iframe 中的下一页 以及一个按钮来显示 iframe 中的上一页 我总共有 4 个页面要在名为 1 html 2 html 3 html 4 html 的 i
  • 平面列表滚动时响应触摸事件的延迟

    我在反应本机应用程序中使用 FlatList 实现了无限滚动 这个列表是一个轮播列表 可以认为是一个很长的列表 当我滚动列表时 列表外部的触摸事件在单击时没有响应 但在 FlatList 滚动完成时响应 我该如何改进这个 这个问题很难回答
  • 在 Javascript 中获取文本框的值

    我有这个html代码 table border cellpadding 3 cellspacing 0 tbody tr td Song td td td tr tbody table
  • 无法读取未定义错误的属性“匹配”

    我试图在 React JS 前端显示一些文本来代替个人资料图像 当它不可用时 基本上 我将当前客户名称传递给一个函数 该函数提取名称中所有单词的第一个字符 我能够仅显示名称 但是当我执行函数调用时 出现 无法读取未定义的属性 匹配 错误 并
  • 更改模板标签 <# {% {{ 等后,John Resig 的微模板出现语法错误

    我在使用 John Resig 的 Micro 模板时遇到了一些麻烦 谁能帮我解释为什么它不起作用 这是模板 以及发动机的改装部分 str replace r t n g split join t replace gt t g 1 r re
  • 正则表达式没有按预期工作?

    我有这个正则表达式 new RegExp a z 0 9 ig 我正在测试一个不应该工作的字符串 vc 但它确实通过了测试 而且它不应该 new RegExp a z 0 9 ig test vc true 但如果我删除其中一个 or or
  • 如何将这段 javascript 代码重写为 C++11?

    这是我在 Javascript Definitive Guide 中看到的 javascript 闭包代码 我想把它写成C 11 var uniqueID1 function var id 0 return function return
  • 单击 div 中的图像时如何翻转该 Div?

    好吧 我对编写 Javascript 知之甚少 我可以对其进行一些编辑 并且涉足了 CSS3 动画 我将向您展示我正在努力实现的目标 然后在下面进行解释 网站布局将是这样的 https i stack imgur com RMb4R jpg
  • 在 Jest 测试中设置时刻时区

    我有 util 函数 它以特定的日期格式解析给定的日期 即 2019 01 28 然后使用momentJS检索当天的开始并将其转换为 ISO 日期格式 dates js import moment from moment export co
  • 根据复选框显示/隐藏输入字段[重复]

    这个问题在这里已经有答案了 如果单击该复选框 它将显示一个输入字段 到目前为止它正在工作 但如果未选中该复选框 它应该隐藏它 我该怎么做 div class checkbox div
  • jquery 中 DOM 元素的手动垃圾回收是否可以提高浏览器性能?

    在性能范围内 删除不再需要的元素是否有意义 或者浏览器是否对代码中未进一步引用的 dom 元素执行自动垃圾收集 some element fadeOut 1000 function el el remove lt does this mak
  • 如何使用 javascript 禁用组合键?

    I would like to disable view source shortcut key for IE using JavaScript To disable Ctrl C I am using the following func
  • AngularJS 中的嵌套模块

    我有 2 个不同的 AngularJs 模块 一个 widgetContainer 和一个 widget 小部件可以显示为独立的应用程序 也可以包含在小部件容器中 一个 widgetContainer 包含 0 N 个 widget 如果我
  • 图像未显示在从 HTML 创建的 PDF 上

    我想动态创建 PDF 这意味着我将从 Google Drive 获取文件 然后将它们放入 HTML 代码中 并尝试从中创建 PDF 一切工作正常 除了图像没有显示 我现在正在做的是 从 HTML 字符串创建 HtmlOutput 获取该 H
  • 出于安全目的,您是否有理由不执行自己的算法来打乱 ID?

    我计划实现我自己的非常简单的 哈希 公式 为具有多个用户的应用程序添加一层安全性 我目前的计划如下 用户创建一个帐户 此时后端会生成一个 ID ID 通过公式运行 假设 ID 57 8926 36 7 或同样随机的东西 然后 我将新的用户
  • Nodejs 解码 base64 并使用流将它们保存到文件中

    在我的node js应用程序中 我使用以下代码行解码base64编码的图像 const fileDataDecoded Buffer from base64EncodedfileData base64 到目前为止 我可以使用以下代码编写一个
  • 如何始终将焦点保持在画布上?

    我一直在这个论坛寻找解决方案 但尚未找到 无论我在页面上的哪个位置单击 我都需要始终将焦点放在画布元素上 我有几个按钮 在每个 onclick 事件中我写 document getElementById canvas focus 这确实有效

随机推荐

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

    我在 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