我目前正在为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
答案 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执行此操作。