CoreGraphics上下文中的透明度/ alpha(iphone,objc)

时间:2010-09-01 10:32:45

标签: iphone objective-c core-graphics alpha cgcontext

我目前正在为iphone制作一个基本的图像编辑器。

我从CGImageRef获取UIImage并使用以下代码为其创建上下文

origImage = result.CGImage;

Iheight = CGImageGetHeight(origImage);
Iwidth = CGImageGetWidth(origImage);
IcolorSpace = CGColorSpaceCreateDeviceRGB();
IrawData = malloc(Iheight * Iwidth * 4);
IbytesPerPixel = 4;
IbytesPerRow = IbytesPerPixel * Iwidth;
IbitsPerComponent = 8;
Icontext = CGBitmapContextCreate(IrawData, Iwidth, Iheight, IbitsPerComponent,
                                 IbytesPerRow, IcolorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big
                                 );
//[bytesPerRow release];
CGContextSetBlendMode(Icontext, kCGBlendModeCopy);
CGContextDrawImage(Icontext, CGRectMake(0,0,Iwidth,Iheight),  origImage);

然后我遍历像素

for (int x=0; x<Iwidth; x++) {
    for (int y=0; y<Iheight; y++) {
            //and  set the alpha component to 0
            int byteIndex = (y*IbytesPerRow) + x*IbytesPerPixel;

            IrawData[byteIndex+3] = 0;

            }
}

然后使用

从上下文创建CGImageRef
    CGImageRef imagea = CGBitmapContextCreateImage(Icontext);

并将CGImage添加到UIImage并分配给UIImageView

问题是alpha的变化不会影响结果图像

如果我用

更改像素的颜色
IrawData[byteIndex+(0/1/2)]

颜色发生变化,但我仍无法更改像素的alpha值

谢谢,

NONONO

1 个答案:

答案 0 :(得分:5)

在更改alpha之前不要忘记对颜色进行多次变换,然后重新预乘它们。

预乘颜色(通常称为“预乘alpha”,这是误导性的)意味着颜色分量已经存储已经乘以alpha,以便于合成。通常的合成(source-over)操作如下所示:

result = (source.rgb * source.a) + (destination.rgb * (1.0 - destination.a));

预乘意味着第一次乘法已经完成,因此可以跳过:

result =  source.rgb             + (destination.rgb * (1.0 - destination.a));

当你在不改变预乘颜色分量的情况下改变alpha时,结果不会改变 - 当你绘制图像时,它看起来没有什么不同,因为颜色仍然被旧的alpha预乘。

所以,你需要预先乘以颜色 - 也就是说,将每个颜色除以alpha(之前它是相乘的,所以你现在必须做反向) - 在你改变alpha之前。然后,在更改alpha之后,通过新的alpha预乘颜色。

当然,这意味着当将alpha更改为零时,所有颜色都将变为黑色(r = g = b = 0)。因此,如果用户可能想要将其更改回来,请确保保留原始图像。

在用户想要的任何alpha中绘制原始图像(不对其进行任何alpha更改)可能会更有效,并且肯定会更容易。您可以在绘制图像之前通过changing your display context's global alpha执行此操作。