如何在Core Graphics中生成RGBA图像?

时间:2011-07-28 15:52:18

标签: iphone objective-c opengl-es core-graphics

我正在尝试从文本生成RGBA8图像以用作OpenGL ES 2.0纹理。

+(UIImage *)imageFromText:(NSString *)text
{
  UIFont *font = [UIFont systemFontOfSize:20.0];  
  CGSize size  = [text sizeWithFont:font];

  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  CGContextRef contextRef =  CGBitmapContextCreate (NULL,
                                                    size.width, size.height,
                                                    8, 4*size.width,
                                                    colorSpace,
                                                    kCGImageAlphaLast
                                                    );
  CGColorSpaceRelease(colorSpace);
  UIGraphicsPushContext(contextRef);

  [text drawAtPoint:CGPointMake(0.0, 0.0) withFont:font];
  UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

  UIGraphicsPopContext();

  return image;
}

不幸的是,没有CGColorSpaceCreateDeviceRGBACGColorSpaceCreateDeviceRGB导致以下错误:

CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 32 bits/pixel; 3-component color space; kCGImageAlphaLast; 448 bytes/row.

我缺少什么来创建OpenGL想要的正确RGBA8格式?

更新:我将CGBitmapContextCreate的最后一个参数从kCGImageAlphaNone(复制时粘贴代码时)更改为kCGImageAlphaLast,这是一个我错误地尝试了几种变体。

更新2 UIGraphicsGetImageFromCurrentImageContext()如果未使用UIGraphicsBeginImageContext()创建上下文,则返回nil,因此必须以不同方式提取图像:[UIImage imageWithCGImage:CGBitmapContextCreateImage(contextRef)]。< / p>

3 个答案:

答案 0 :(得分:14)

您在创建过程中指定的颜色空间不会导致类似的错误。

您收到该错误的原因是您为每个组件指定了8位,可能是您为4*size.width传入的bytesPerRow值中的4个颜色组件,但是bitmapInfo } kCGImageAlphaNone的参数。 kCGImageAlphaNone仅表示RGB,而非RGBA。如果您需要RGBA,则最有可能指定 kCGImageAlphaLast kCGImageAlphaPremultipliedLast

[编辑]抱歉。我应该说kCGImageAlphaPremultipliedLast,而不是kCGImageAlphaLast

所以,像这样:

CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
CGContextRef contextRef =  CGBitmapContextCreate(NULL,
                                                 size.width,
                                                 size.height,
                                                 8,
                                                 4 * size.width,
                                                 colorSpace,
                                                 kCGImageAlphaPremultipliedLast);

答案 1 :(得分:1)

即使我使用unsupported parameter combination,我也遇到了同样的kCGImageAlphaPremultipliedLast错误。在我的案例中的问题原来是我得到的宽度是分数。通过将int(width)传递给CGBitmapContextCreate将其转换为整数解决了这个问题。

- 编辑以回应史蒂文的评论 -

以小数宽度作为第二个参数输入的问题不是CGBitmapContextCreate如此解释它 - 如上所述,它被隐式地转换为参数的无符号整数类型。相反,它在bytes_per_row参数中产生差异,因为int(width * 4)与int(width)* 4不同。例如。如果宽度为22.5,则宽度将被截断为22,但width * 4计算为90,而不是88.

答案 2 :(得分:0)

    CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);

    CGBitmapInfo    bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little;

    CGContextRef theContext = CGBitmapContextCreate(NULL, imgSize.width, imgSize.height, 8, 4*imgSize.width, colorSpace, bitmapInfo);