ImageMagick“颜色转透明”(类似于GIMP)

13

我正在尝试完成GIMP在使用实际颜色选择“颜色变透明”时的操作。

我有一张图片,其中包含颜色# a0132e,我希望将其转换为透明度。不仅是这种确切颜色,而且任何偏离它的颜色都必须变得更半透明。这就是GIMP中“颜色变透明”所做的事情。

我已经尝试了很多不同的方法,但我无法理解它。我已经用了几个小时来尝试使用-fx参数及其绝对奇怪的语法,但这根本没有帮助。也许使用convert的一些选项可以完成此操作,但我还没有找到正确的方法,而且我已经尝试过谷歌搜索出来的所有方法。

理想情况下,我想创建一个可以像这样调用的脚本:

color-to-alpha.cmd original.png output.png #a0132e

或类似的命令。我该如何做到这一点?


1
那么,你能给我们展示一下你的图片吗?"that much semi-transparent"是什么意思? 我的意思是 #a0132f#a0132e 是不同的,那么透明度应该变成多少呢?99%?22%?还是 "semi-transparent" 总是表示50%?你是在Windows 还是OSX上? - Mark Setchell
2
GIMP是什么。对于我的用例来说,那正是完美的效果。 - Thany
3个回答

32

1. ImageMagick命令行参数基础知识

首先:请阅读我的答案"ImageMagick Command-Line Option Order (and Categories of Command-Line Parameters)"。它解释了ImageMagick命令行结构的一些基础知识。具体来说,它解释了以下几点之间的主要区别:

  1. 图像设置
  2. 图像操作符
  3. 图像序列操作符

这些差异是必须理解的关键概念,以便能够分析复杂的ImageMagick命令行。

2. ImageMagick 'aside'处理基础知识

建议使用的命令相当高级。它使用括号来分隔完成的命令行的两个不同部分。

带括号的命令部分允许在主命令“旁边”处理图像:

它允许您在一个单独的图像列表上进行一些工作,然后将该单独处理的结果放置到前一个列表的末尾。(您可以使用多个,甚至可以在单个ImageMagick命令行中使用嵌套的带括号的图像处理操作。)在某种程度上,它充当了一个临时的工作区域,在其中对一组图像进行处理,并将结果放回到主图像列表中。

任何一对括号的开头(“(”)都会开始一个新的图像列表。括号内所有连续的参数只适用于新的图像列表。相应括号对的结束(“)”)部分最终化所有的“旁边”处理,并将来自“旁边”的结果图像列表(可能由零、一个或多个图像组成)放置到主图像列表中。

我对@dlemstra的原始命令所做的唯一的轻微更改:我用反斜线转义了()的出现,并将其替换为\(\)。这是必需的,以便像Bash这样的shell不会尝试将这些字符误解为表示子shell的开始和结束。

需要注意的重要事项:当您使用()分隔符进行旁边处理时,必须在它们周围留出空格--否则它们将无法工作!

3. 重新格式化原始命令

首先,我会对@dlemstra最初提出的命令进行一些重新格式化。这大体上并不改变它的含义。它只是将每个设置和每个操作放在自己的行上。

(这适用于Mac OSX和Linux--对于Windows,请将所有\行延续符替换为^。)

convert                        \
    original.png               \
    \(                         \
       -clone 0                \
       -fill "#a0132e"         \
       -colorize 100           \
    \)                         \
    \(                         \
       -clone 0,1              \
       -compose difference     \
       -composite              \
       -separate               \
       +channel                \
       -evaluate-sequence max  \
       -auto-level             \
    \)                         \
     -delete 1                 \
     -alpha off                \
     -compose over             \
     -compose copy_opacity     \
     -composite                \
    output.png

4. 现在逐行解析这个庞然大物的命令

  1. Line 1: convert
    这是要运行的ImageMagick命令

  2. Line 2: original.png
    这是要处理的第一个输入图像。 此时,这是主图像列表中唯一的图像。

  3. Line 3: \(
    打开一个新的(空)图像列表,以便“在旁边”处理。

  4. Line 4: -clone 0
    “-clone”是一个图像堆栈运算符。 它请求制作上一个'pushed'图像序列的那个图像的克隆。 最后一个推送的图像序列的最后一个图像的索引为0。 换句话说:将 original.png 的副本放入当前的“旁边”图像列表中。

  5. Line 5: -fill "#a0132e"
    “-fill”是一个图像设置。 它定义了在填充图形原语时要使用的填充颜色。 "#a0132e"是一种红色。

  6. Line 6: -colorize 100
    “-colorize”是一个图像操作。 它通过指定的量(此处为 100 )使用最近的 -fill 设置指定的颜色来对图像进行着色。 结果现在是与 original.png 大小相同的图像。 该图像具有统一的颜色“#a0132e”。 换句话说:新创建的图像是一个带有与 original.png 相同大小的红色补丁。

  7. Line 7: \)
    这关闭了旁边的处理并将其产生的图像放置在主图像列表的末尾。 现在,主图像列表中有两个图像: original.png 和具有相同大小的红色统一颜色的一个,该图像是在“旁边”进程中创建的。

  8. Line 8: `(
    为另一个“旁边”处理打开另一个新图像列表。

  9. Line 9: -clone 0,1
    “-clone”仍然是一个图像堆叠运算符。 这里它要求克隆索引为 0 1 的每个图像。 换句话说:将 original.png 的副本和均匀着色的“reddish”的副本放入当前的“旁边”列表中。

  10. Line 10: -compose difference
    “-compose”是一个图像设置。 它定义了稍后要使用的特定合成算法,在我们的情况下为差异

  11. Line 11: -composite<

    如果您对此不熟悉,这里有一个额外的提示。

    您可以插入

     +write output-destination
    

    (几乎)可以在命令行的任何位置插入+write操作符——甚至可以插入多次。然后write操作符将以其当前处理状态,将当前加载的图像(或当前加载的图像序列)写入给定的输出目标。

    此输出目标可以是文件,也可以是show:或其他IM输出支持的内容。在输出后,原始命令的处理将恢复并继续执行。

    当然,只有在第一张(或其他任何)图像(序列)操作符之后(而不是任何图像设置之后),才有意义插入+write操作符——否则当前图像列表将没有改变。

    如果存在多个输出图像(因为当前图像列表包含多个图像),则ImageMagick会自动为相应的文件名分配索引号。

    这是一个很棒的技巧!如果您开始将其用于自己的ImageMagick命令开发中,您很快就会发现它是不可或缺的。它有助于调试(或优化、简化……)复杂的命令设置。

    6.带适当+write filename的修改后的命令行

    如果您想要对图像设置、图像操作和图像序列操作逐行解释进行“视觉增强”,那么运行此修改后的命令。查看每个由+write命令创建的图像,并将其与本答案第4节中的相应解释进行比较:

    convert                                 \    
        original.png                        \    
        \(                                  \    
           -clone 0                         \    
           -fill "#a0132e"                  \    
           -colorize 100                    \    
        \)                                  \    
        +write 0---after-aside1.png         \    
        \(                                  \    
           -clone 0,1                       \    
           +write 1---aside2-cloned.png     \    
           -compose difference              \    
           -composite                       \    
           +write 2---aside2-composite.png  \
           -separate                        \    
           +write 3---aside2-separate.png   \
           +channel                         \    
           -evaluate-sequence max           \    
           +write 4---aside2-evaluate.png   \
           -auto-level                      \    
           +write 5---aside2-autolevel.png  \   
        \)                                  \    
         +write 6---after-aside2.png        \    
         -delete 1                          \    
         +write 7---main-after-delete.png   \
         -alpha off                         \    
         -compose over                      \    
         -compose copy_opacity              \    
         -composite                         \    
         +write 8---main-composite.png      \    
        output.png
    

    7. 显示原始、中间和输出图像如下

    好的,同时我已经在一张输入图片上运行了之前的命令。下面的图片展示了它与原始图片并排显示。也许我挑选用于测试的 original.png 并不适合与颜色 '#a0132e' 进行对比测试。但由于 @Thany 没有回应 @MarkSetchells 的评论要求提供一个示例图像,你们只能接受我的选择:

    原始(左)和输出图像(右)

    这是使用多个 +write 添加到原始命令行的修改后的命令结果。

    如预期的那样,original.png 看起来与它的克隆以及其他几个克隆图像相同。

    具有相同前缀 1---2---... 的多个文件名是由同一 +write 命令产生的,该命令在当前加载的图像列表中找到多个要保存的图像。

    原始图像(左上方),中间处理结果和输出图像(右下角)

    8. 给读者的练习

    检查我的关于第19行第20行无效的说法是否正确。从命令行中删除 -compose over 并测试结果是否仍然相同。


    更新

    我最初编写这个答案是为了详细解释 @dlemstra 给出的命令行。Dirk 的答案基于 ImageMagick 脚本 color2alpha,该脚本是由 Fred Weinhaus 编写的。我现在才更仔细地看了一下 Fred 的脚本:

    Fred 的脚本提供了一些额外且非常巧妙的选项:

    1. 它可以指定输入图像中的任何颜色作为创建渐变 alpha 通道的基础。
    2. 它可以指定另一种颜色来替换输出中的 alpha 颜色。
    3. 它实现了一个“增益”控制,允许影响 alpha 通道中白色到黑色的过渡。

4
这是有史以来最好的回答之一。 - dax
@dax:微笑谢谢夸奖。但我认为你是很少有人这么想的 :-) - Kurt Pfeifle
1
你的序列输出看起来有些可疑。原始图像大部分是蓝色,中心为橙白色,而要转换为透明度的颜色是红色。我期望输出会在相反的方向上被严重着色,变成绿色。这正是GIMP生成的效果。但是你的输出看起来更像是变得中性透明了。 - Ruslan
syntax error near unexpected token `(' - Eduardo Lucio

6

ImageMagick没有内置的颜色转透明度算法。Fred Weinhaus提出了以下解决方案,几乎与GIMP的颜色转透明度插件相同。

convert original.png ( -clone 0 -fill "#a0132e" -colorize 100 ) ( -clone 0,1 
-compose difference -composite -separate +channel -evaluate-sequence max
-auto-level ) -delete 1 -alpha off -compose over -compose copy_opacity -composite
output.png

1
看起来够复杂,应该可以工作:P 我有机会就试试。但遗憾的是我不完全确定这个序列在做什么,但我想理解它(如果它起作用的话)... - Thany
@Thany:在评论中解释这个命令是不可能的。我会为此添加一个额外的答案... - Kurt Pfeifle

3

我不知道是否理解了问题的意思...但是,如果你想将一个纯蓝色("blue", "#0000ff")替换为透明度(Alpha通道),例如,请使用以下命令...

convert "input.png" -transparent "#0000ff" -alpha Associate "output.png"

注:
I - 我在@dlemstra和@Kurt Pfeifle的答案中遇到了以下错误:syntax error near unexpected token `(';
II - color2alpha 方法会引起副作用。原本不是纯蓝色 ("blue", "#0000ff") 的颜色变成了半透明,图片上有一种蓝色残留物,在对修改后的图像进行某些操作时会出现。
III - -alpha Associate 参数减少了在对修改后的图像进行某些操作时出现的蓝色残留物。事实上,我们得到了黑色,这在大多数情况下更好。

提示: 可以使用参数-fuzz NUMBER%使透明度达到并非完全是蓝色(我们的示例)的颜色。

[参考文献: https://legacy.imagemagick.org/discourse-server/viewtopic.php?p=41925#p41925,https://legacy.imagemagick.org/discourse-server/viewtopic.php?p=65754&sid=7cfdfe8f5d3bd65e9da0b40f78e234d6#p65754]


1
如果您只想使颜色透明,可以跳过“-alpha Associate”。到目前为止,这是最简单的解决方案。 - dibery
@dibery 使用-alpha Associate的原因在“注释”项“III”中。 - Eduardo Lucio
1
是的,我明白了。只需为那些不需要此功能的人留下一条注释即可。无论如何,感谢您的解释。 - dibery

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接