对于我的iPhone 3D应用程序,我目前正在使用CoreGraphics来加载预先乘以alpha的png文件。以下是要点:
// load a 4-channel rgba png file with pre-multiplied alpha.
CGContextRef context =
CGBitmapContextCreate(data, width, height, 8, num_channels * width, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
// Draw the image into the context
CGRect rect = CGRectMake(0, 0, width, height);
CGContextDrawImage(context, rect, image);
CGContextRelease(context);
然后我继续使用数据作为OpenGL中的纹理。
我的问题:通过指定预乘的alpha - kCGImageAlphaPremultipliedLast - 我 - 无意中 - 告诉CoreGraphics将rgb通道乘以alpha或 - 我所假设的 - 我只是指出输入图像的格式已经预先乘以alpha?
谢谢, 道格
答案 0 :(得分:4)
通过指定预乘的alpha - kCGImageAlphaPremultipliedLast - 我 - 无意中 - 告诉CoreGraphics将rgb通道乘以alpha或 - 我所假设的 - 我只是表明输入图像的格式已预先乘以alpha?
都不是。您指定了目标(上下文)的格式,而不是源。源 - 图像对象 - 知道它的像素的颜色是否被预乘,并且当它将源图像绘制到上下文中时,Quartz将使用该知识做正确的事情。
这意味着缓冲区中的像素将被预乘 - 而不是两次,但是它们将在上下文缓冲区中预乘,无论源颜色是否被预乘(如果它们是,则不需要)再次繁殖;如果不是,那么它将第一次成倍增加。)
我不知道OpenGL知道这是否有问题,如果是,可能没有解决此代码的方法:在Mac上,至少Quartz does not support unpremultiplied colors in bitmap contexts。
您可以尝试this storage format。
答案 1 :(得分:2)
为了将来参考绊到这个问题的人,这里有一个关于如何去预乘的例子:
/////// ....
/////// load the image into imageRef up here
/////// e.g. with CGImageSourceCreateWithURL(); and CGImageSourceCreateImageAtIndex(); on OS X
/////// or, by accessing CGImage property of UIImage
///////
/////// then extract bitsPerComponent, bytesPerRow and color space
/////// ....
// draw CG image to a byte array
CGContextRef bitmapContext = CGBitmapContextCreate(img->data,
img->w, img->h,
bitsPerComponent,
bytesPerRow,
space,
kCGImageAlphaPremultipliedLast);
CGContextDrawImage(bitmapContext,CGRectMake(0.0, 0.0, (float)img->w, (float)img->h),imageRef);
CGContextRelease(bitmapContext);
// let's undo premultiplication
for(int i=0; i < bytesPerRow * img->h; i+=4)
{
for(int j=0; j<3; j++)
{
img->data[i+j] = img->data[i+j] / (img->data[i+3]/255.);
}
}