曾经有一张图像,可能带有Alpha透明度,覆盖在白色背景和黑色背景上。我可以访问两个结果图像,但不能访问原始图像,我想检索原始图像。
我编写了一些Ruby代码来执行此操作,但是,我认为仅仅本质上是在Ruby中,它并不像它需要的那么快。这是基本逻辑,逐像素迭代:
if pixel_on_black == pixel_on_white
# Matching pixels indicate 100% opacity in the original.
original_pixel = pixel_on_black
elsif color_on_black == BLACK && color_on_white == WHITE
# Black on black and white on white indicate 0% opacity in the original.
original_pixel = TRANSPARENT
else
# Since it's not one of the simple cases, then we'll do some math.
# Fancy algebra tells us the following. (MAX_VALUE is the largest value
# a channel can have. So, in most cases, 255.)
# First, find the alpha value. This equation follows from the equations
# for composing on black and composing on white.
alpha = pixel_on_black.red - pixel_on_white.red + MAX_VALUE
# Now that we know the alpha value, undo its multiplicative effect on the
# pixel on black. By dividing. Ta da.
alpha_ratio = alpha / MAX_VALUE
original_pixel = Pixel.new
original_pixel.red = pixel_on_black.red / alpha_ratio
original_pixel.green = pixel_on_black.green / alpha_ratio
original_pixel.blue = pixel_on_black.blue / alpha_ratio
original_pixel.alpha = alpha
end
这样很好,而且很有效。但是,这段代码最终需要以超快的速度运行,并且Ruby中的迭代像素是不可接受的。看起来,除非这个函数已经存在于某个地方,否则最好还是想出一系列可以解决问题的ImageMagick选项。
我正在研究ImageMagick的命令行工具,因为它看起来非常非常强大,看起来像-fx
或一系列花哨的-function
参数会和我的代码做同样的事情以上。我也会一直在努力,但有没有ImageMagick专业人士已经知道如何将所有这些放在一起?
编辑:我现在正在运行-fx
版本:)
convert image_on_black.png image_on_white.png -matte -channel alpha -fx "u.r + 1 - v.r" -channel RGB -fx "(u.a == 0) ? 1 : (u / u.a)" output.png
几乎是原始代码的精确翻译,分为多个频道。迭代alpha通道,并设置正确的alpha值。然后迭代RGB通道,并将通道除以alpha值(除非它为零,在这种情况下我们可以将其设置为任何值,因为除以零会引发错误 - 在这种情况下,我选择1作为白色)。 / p>
现在是时候将这些转换为更明确的参数,因为-fx
表达式会针对每个像素重新评估,这不是很好。
答案 0 :(得分:0)
Mkay,我在这里感到很惊讶,我想我找到了答案。这是四个ImageMagick命令,虽然它们可能会以某种方式合成一个......但我怀疑它。
convert input_on_white.png -channel RGB -negate /tmp/convert_negative.png && \
convert input_on_black.png /tmp/convert_negative.png -alpha Off -compose Plus -composite /tmp/convert_alpha.png && \
composite plasma2.png /tmp/convert_alpha.png -alpha Off -channel RGB -compose Divide /tmp/convert_division.png && \
convert /tmp/convert_division.png /tmp/convert_alpha.png -compose CopyOpacity -composite plasma_output.png
(显然,完成后,清理那些临时文件。另外,使用实际的临时文件系统,而不是使用硬编码路径。)
策略是首先创建一个代表alpha蒙版的灰度图像。我们将模拟代码行alpha = pixel_on_black.red - pixel_on_white.red + MAX_VALUE
,可以将其重写为alpha = pixel_on_black.red + (MAX_VALUE - pixel_on_white.red)
。
所以,第1行:我们创建一个代表该等式的第二项的图像,这是白色图像的RGB通道的否定版本。我们将其保存为临时文件。
然后,第2行:我们想将该负像添加到黑白图像上。使用ImageMagick的Plus组合,并将其保存为临时alpha掩码。结果是灰度图像,其中白色表示在最终图像中应具有100%不透明度的区域,黑色表示稍后将完全透明的区域。
然后,第3行:将黑色图像恢复为原始RGB颜色。由于黑色图像是通过使用alpha比率对RGB通道进行多重创建而创建的,因此我们除以alpha蒙版图像以撤消该效果。
最后,第4行:从第3行获取经过颜色校正的图像,并使用ImageMagick的CopyOpacity合成函数应用第2行的alpha蒙版。塔达!
我原来的策略需要5-10秒。这种策略只需不到一秒钟。好多了,好多了。
不出所料,寻求帮助是驱使我自己找到答案的原因。无论如何,我会将这个问题保持开放48小时,以确定是否有人找到了更优化的解决方案。谢谢!