寻找与预乘alpha一起使用的一些帮助

时间:2010-05-24 23:43:07

标签: iphone c objective-c

我正在尝试使用多个目标图像的内容更新源图像。从我所知道的使用预乘alpha是这样的方法,但我认为我做错了(下面的功能)。我开始使用的图像被初始化,所有ARGB值都设置为0.当我运行该函数时,生成的图像看起来很棒,但是当我开始合成任何其他像素时,所有具有alpha信息的像素都会变得混乱。有没有人知道我是否做了一些明显错误的事情,或者我是否需要做一些额外的修改颜色值?

void CompositeImage(unsigned char *src, unsigned char *dest, int srcW, int srcH){
int w = srcW;
int h = srcH;

int px0;
int px1;
int px2;
int px3;

int inverseAlpha;

int r;
int g;
int b;
int a;

int y;
int x;

for (y = 0; y < h; y++) {
    for (x= 0; x< w*4; x+=4) {
        // pixel number
        px0 = (y*w*4) + x;
        px1 = (y*w*4) + (x+1);
        px2 = (y*w*4) + (x+2);
        px3 = (y*w*4) + (x+3);

        inverseAlpha = 1 - src[px3];

        // create new values
        r = src[px0]  + inverseAlpha * dest[px0];
        g = src[px1]  + inverseAlpha * dest[px1];
        b = src[px2]  + inverseAlpha * dest[px2];
        a = src[px3]  + inverseAlpha * dest[px3];

        // update destination image
        dest[px0] = r;
        dest[px1] = g;
        dest[px2] = b;
        dest[px3] = a;
    }
}

}

1 个答案:

答案 0 :(得分:2)

我不清楚您正在使用哪些数据。您的源图像在存储时是否已预先乘以alpha值?如果没有,那么预乘的alpha不适用于此处,你需要进行正常的alpha混合。

无论如何,代码中的一个大问题是你没有跟踪你正在处理的值范围。

inverseAlpha = 1 - src[px3];

这需要更改为:

inverseAlpha = 255 - src[px3];

这里有所有积分值类型,因此正常的输入0..255值范围将导致inverseAlpha范围为-254..1,这将给你一些真正古怪的结果。

将1更改为255后,您还需要将每个通道的结果除以255,以将它们缩小到适当的范围。另一种方法是使用浮点数而不是整数进行中间计算,并将初始通道值除以255.0(而不是这些其他更改),以获得0..1范围内的值。

如果您的源数据确实已经预先乘以alpha,那么结果行应该如下所示。

r = src[px0]  + inverseAlpha * dest[px0] / 255;

如果你的源数据没有预乘的alpha,那么它应该是:

r = src[px0] * src[px3] / 255  + inverseAlpha * dest[px0] / 255;

混合alpha通道没什么特别之处。使用与r,g和b相同的计算。