1

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

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

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

谢谢,

不不不

4

1 回答 1

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 更改)可能会更有效,并且肯定会更容易。您可以通过在绘制图像之前更改显示上下文的全局 alpha来做到这一点。

于 2010-09-01T12:55:13.360 回答