我有一个 PNG(带有 alpha channel ),我希望使用 CGContextDrawImage 将其合成到 CGContextRef 上。我希望合成 RBG channel ,但我也希望将源图像的 alpha channel 也复制过来。
最终,我会将最终的 CGContextRef(以 CGImageRef 的形式)传递给 GLKit,我希望在其中使用片段着色器来操纵 alpha channel 以进行颜色着色。
不幸的是,我在使用 Core Graphics 创建纹理图集时遇到了问题。看起来最终的 CGImageRef 无法从我的源图像复制 alpha channel 并且是不透明的。我在下面附上了我当前的合成代码和我的测试图像的副本:
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
UInt8 * m_PixelBuf = malloc(sizeof(UInt8) * atlasSize.height * atlasSize.width * 4);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * atlasSize.width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(m_PixelBuf,
atlasSize.width,
atlasSize.height,
bitsPerComponent,
bytesPerRow,
colorSpace
kCGImageAlphaPremultipliedFirst);
CGContextDrawImage(context, CGRectMake(x, y, image.size.width, image.size.height), image.CGImage);
CGImageRef imgRef = CGBitmapContextCreateImage(context);
CGColorSpaceRelease(colorSpace);
CGContextRelease(context);
最佳答案
你们在哪里可以找到使用 CGBitmapContextCreate
的过程,因为这是最常见的问题之一:kCGImageAlphaPremultipliedFirst
会将 alpha 设置为 1,并使用 alpha PREMULTIPLY RGB值(value)。
如果您使用的是 Xcode,请使用命令单击 kCGImageAlphaPremultipliedFirst
并找到合适的替换项,例如 kCGImageAlphaLast
。
添加一个使用 alpha 作为最后一个 channel 的例子:
+ (UIImage *)generateRadialGradient {
int size = 256;
uint8_t *buffer = malloc(size*size*4);
memset(buffer, 255, size*size*4);
for(int i=0; i<size; i++) {
for(int j=0; j<size; j++) {
float x = ((float)i/(float)size)*2.0f - 1.0f;
float y = ((float)j/(float)size)*2.0f - 1.0f;
float relativeRadius = x*x + y*y;
if(relativeRadius >= 0.0 && relativeRadius < 1.0) { buffer[(i*size + j)*4 + 3] = (uint8_t)((1.0-sqrt(relativeRadius))*255.0); }
else buffer[(i*size + j)*4 + 3] = 0;
}
}
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL,
buffer,
size*size*4,
NULL);
int bitsPerComponent = 8;
int bitsPerPixel = 32;
int bytesPerRow = 4*size;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Big|kCGImageAlphaLast;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGImageRef imageRef = CGImageCreate(size,
size,
bitsPerComponent,
bitsPerPixel,
bytesPerRow,
colorSpaceRef,
bitmapInfo,
provider,
NULL,
NO,
renderingIntent);
/*I get the current dimensions displayed here */
return [UIImage imageWithCGImage:imageRef];
}
所以这段代码从代码中创建了一个径向渐变。内部完全不透明,离中心越远越透明。
我们还可以使用 kCGImageAlphaFirst
,它会产生黄色渐变。 Alpha 始终为 1,只有第一个(红色) channel 正在减少。结果是中间是白色,随着红色 channel 的减少,黄色开始显示。
关于ios - 使用 Core Graphics 合成图像并保留 alpha channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24163596/