2011-05-14 87 views
1

曾經有一個圖像可能具有alpha透明度,覆蓋在白色背景和黑色背景上。我可以訪問這兩個結果圖像,但不是原始圖像,我想檢索原始圖像。使用ImageMagick從兩個合成圖像中檢索原始蒙版

我已經寫了一些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代表白色)。

現在可以將這些轉換爲更明確的參數,因爲-fx表達式針對每個像素進行了重新評估,這並不是很好。

回答

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 = 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行:使用ImageMagick的CopyOpacity組合函數從第3行取得經過顏色校正的圖像,並應用第2行的alpha蒙版。達達!

我原來的策略需要5-10秒。這個策略不到一秒鐘。好多了,好多了。

不出所料,尋求幫助是什麼驅使我自己找到答案。無論如何,我會在48小時內解決這個問題,看看是否有人找到一個更優化的解決方案。謝謝!