2009-11-08 37 views
1

想象一下,您有两个图像A和B以及第三个灰度图像T.A和B几乎包含任何东西,但让我们假设它们是来自游戏的两个场景。如何使用灰度转换贴图在两个图像之间转换

现在,假设T包含一个菱形渐变。灰度,从外面的黑色到内部的白色。随着时间的推移,我们假设256没有进一步详细阐述与“灰度”相匹配的灰度,A应该过渡到B,从而产生钻石擦拭效果。如果T代替了一个较小的矩形渐变网格,它就像图像的每个部分本身做了一个矩形的擦拭。

如果你曾经使用RPG Maker或大多数视觉新颖的引擎,你可能会认识到这个概念。

课程的问题是如何做到这一点。我知道它涉及A和B之间的每像素混合,但这就是我得到的。

对于额外的奖励,软边呢?

而现在,结论

Final experiment, based on eJames's code

Sample from final experiment -- waves up, 50% http://helmet.kafuka.org/TransitionsSample.png

回答

4

T图像中的灰度值表示时间偏移。你擦的效果将基本上如下工作,在每个像素的基础:

for (timeIndex from 0 to 255) 
{ 
    for (each pixel) 
    { 
     if (timeIndex < T.valueOf[pixel]) 
     { 
      compositeImage.colorOf[pixel] = A.colorOf[pixel]; 
     } 
     else 
     { 
      compositeImage.colorOf[pixel] = B.colorOf[pixel]; 
     } 
    } 
} 

为了说明,假设在timeIndex几个值会发生什么:

  1. timeIndex == 0(0%):这是转型的开始。此时,合成图像中的大部分像素将是图像A的像素,除非T中的对应像素完全是黑色。在这些情况下,合成图像像素将是图像B的像素。

  2. timeIndex == 63(25%):在这一点上,来自图像B的更多像素已经使其进入合成图像。 T的值小于25%的每个像素将从图像B中获取,其余的仍然是图像A.

  3. timeIndex == 255(100%):此时,T中的每个像素都将否定条件,所以所有的合成图像中的像素的将是那些图像B.

以“平滑”过渡的,你可以做到以下几点:

for (timeIndex from 0 to (255 + fadeTime)) 
{ 
    for (each pixel) 
    { 
     blendingRatio = edgeFunction(timeIndex, T.valueOf[pixel], fadeTime); 
     compositeImage.colorOf[pixel] = 
        (1.0 - blendingRatio) * A.colorOf[pixel] + 
        blendingRatio * B.colorOf[pixel]; 
    } 
} 

edgeFunction的选择取决于你。这一个产生从A到B的线性转变:

float edgeFunction(value, threshold, duration) 
{ 
    if (value < threshold) { return 0.0; } 
    if (value >= (threshold + duration)) { return 1.0; } 

    // simple linear transition: 
    return (value - threshold)/duration; 
} 
+0

恭喜!预先计算混合比率并使用直接位图操作,可以使您的方法更快速。 – Kawa 2009-11-09 17:03:24

+0

很高兴听到它:) – 2009-11-09 17:13:59

+1

并感谢您发布您的最终代码。很高兴看到这样的答案得到付诸实践,现在其他人可以从你所做的改进中学习。干杯! – 2009-11-09 17:16:58

1

我说你开始像A,然后在我的每一步你使用图像A的像素,每个位置其中T小于I,否则图像B的像素。

对于软边缘可以定义另一个参数d,并计算出你喜欢这么个像素P:

对于每个点(x,y)的您提供以下三个选项之间做出选择:

  • 我(x,y)-d然后该点等于A的点,则T(x,y)+ d然后令z = I - (T (x,y)-d)并且该点等于A(x,y)(1-z /(2d))+ B(x,y)(z /(2d))
  • 我< T(X,Y)+ d那么点等于B

这产生了直线边缘的点,当然也可以用于边缘的功能的任意数目之间选择。