对未预乘 RGB + Alpha 的透明度

平面设计 adobe-photoshop 透明度
2022-01-19 17:48:54

我在 Photoshop CS5 中有一个透明层(所以在内部,它很可能存储为未预乘的 RGB 分量加上每个像素的 alpha 分量)。

现在我想将其转换为不透明层(只是未预乘的 RGB)+ alpha 蒙版。结果应该和原来的一样。

我不能只用黑色覆盖透明层,将其作为蒙版并合并图层,因为这会导致 alpha 在 RGB 值中被预乘。

我希望你能理解这个问题,并能给我一个解决方案。

作为另一种解释:我想要这个 REVERSE 过程:

  1. 创建一个新图层并粘贴到任何图像中
  2. 创建具有白到黑渐变的蒙版
  3. 应用图层蒙版

说明图片:

状态 A: 在此处输入图像描述

状态 B: 在此处输入图像描述


重要提示:该层仅用于此示例完全恒定的红色 - 但您可以想到任何任意图像而不是恒定红色。所以 - 要从状态 A 到状态 B,只需应用图层蒙版。

我想知道如何从 B 国到 A 国。

4个回答

我完全理解你的痛苦。这是我的解决方案 :)
将 Alpha 提取为遮罩动作
这是它的作用:

在此处输入图像描述 编辑:
在此处输入图像描述
我希望这会有所帮助:)


错误的!都错了!

在这个过程中我欺骗了自己,你也欺骗了自己:我创造的确实是一个预乘的图像——不是用黑色预乘的,而是用白色预乘的。我将这个答案留给其他人在此基础上构建。


我设法这样做:

  1. 从图像中提取真正的 RGBA 通道
  2. 使用它们构建新图像

我是这样做的:

测试图像

这是我使用的测试图像。PS 中的频道视图如下所示:

渠道

通过选择单独的通道,我将它们复制到单独的图层中,然后用白色背景将它们展平以接收黑白地图,如下所示:

体重地图

我还通过命令单击图层缩略图并用选择填充新图层来将原始图像的透明度提取到图层中。

然后我创建了一个具有相同尺寸且没有透明度的新图像。然后我将创建的 RGB 图层粘贴到新图像的相应通道中:

新图像的频道

在最后一步中,我通过双击“展开”图层,并使用原始图像中的 alpha 图层创建了图层蒙版,结果如下:

图层蒙版


如上所述,这不会创建未预乘的图像,因为我的示例必须看起来像这样才能未预乘:

正确版本

有没有人比我聪明并且可以创造这个?我认为如果没有先进的基于像素的脚本,这在 Photoshop 中是不可能的。

好的 - 我创建了一个简单的 pixelBender 过滤器,可以与 photoshop PixelBender 插件 (http://labs.adobe.com/downloads/pixelbenderplugin.html) 一起使用,以删除图层的透明度。这里是: http: //neo.cycovery.com/removeTransparency.pbk

根据给出的答案和你的评论,简短的回答是:你不能做你想做的事。应用蒙版后,将渲染图层并丢弃看不见的图像数据。

编辑:

我制作了一些示例 png 文件,然后使用 php 来操作它们(源代码如下)。

如果我创建一个具有随机透明度的 png 并在图层具有蒙版时保存,那么无论是否启用了 alpha 支持,100% 透明区域(例如来自方框工具)都会显示为白色。包含一定量 100% 透明的渐变不会在禁用 alpha 的情况下显示。

如果我(永久)应用图层蒙版,然后创建 png,则如果禁用了 alpha,则 php 会提供原始图像。

因此,一个潜在的解决方法是找到一个不支持 alpha PNG 的软件包并从那里重新保存。至于恢复原来的面具,我还没有看。

两个代码示例都是概念验证和慢速。

<?php

$im = imagecreatefrompng('./images/alphatest_nolayer.png');
$enable_alpha = 0;  //set to 0 to disable aplha

if ($enable_alpha) {
    imagealphablending($im, false);
    imagesavealpha($im, true);
}

header('Content-Type: image/png');
imagepng($im);

imagedestroy($im);

?>

要提取 alpha(注意:php 的 GD 限制为 128 级 alpha,而不是 256),因此会丢失一些精度。可以使用级别工具将 alpha 拉伸到 256)

<?php

$im = imagecreatefrompng('./images/alphatest_nolayer.png');
$w = imagesx($im);
$h = imagesy($im);

$om = imagecreatetruecolor($w,$h);

for ($x = 0; $x < $w; $x++) {
    for ($y = 0; $y < $h; $y++) {
        $rgb = imagecolorat($im, $x, $y);
        $colors = imagecolorsforindex($im,  $rgb);

        $orgb = imagecolorallocate($om,$colors['alpha'],$colors['alpha'],$colors['alpha']);
        imagesetpixel($om,$x,$y,$orgb);
    }
}

header('Content-Type: image/png');
imagepng($om);

imagedestroy($om);
imagedestroy($im);

?>