【问题标题】:How do you generate an RGBA image in Core Graphics?如何在 Core Graphics 中生成 RGBA 图像?
【发布时间】:2011-07-28 15:52:18
【问题描述】:

我正在尝试从文本生成 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;
}

很遗憾,没有CGColorSpaceCreateDeviceRGBA,而CGColorSpaceCreateDeviceRGB 会导致以下错误:

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:如果上下文不是使用 UIGraphicsBeginImageContext() 创建的,UIGraphicsGetImageFromCurrentImageContext() 返回 nil,因此需要以不同的方式提取图像:[UIImage imageWithCGImage:CGBitmapContextCreateImage(contextRef)]

【问题讨论】:

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


    【解决方案1】:

    您在创建过程中指定的色彩空间不会导致这样的错误。

    您收到该错误的原因是您为每个组件指定了 8 位,大概是您为 bytesPerRow 传入的 4*size.width 值中的 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);
    

    【讨论】:

    • 我也试过了;不幸的是,我收到了相同的(ish)错误:“CGBitmapContextCreate:不支持的参数组合:8 个整数位/分量;32 位/像素;3 分量颜色空间;kCGImageAlphaLast;448 字节/行。”
    • 我已经更新了问题以表明 kCGImageAlphaLast 仍然出现错误。
    • @Ian Terrell:是的,对不起,我弄错了;用kCGImageAlphaPremultipliedLast而不是kCGImageAlphaLast查看我的更新答案。
    • 这确实修复了错误;我的 UIImage 进一步创建不正确,但我通过 image = [UIImage imageWithCGImage:CGBitmapContextCreateImage(contextRef)] 解决了这个问题。谢谢!
    • Apple 文档说从 2.0 开始支持 kCGImageAlphaXX,但实际上只有 kCGImageAlphaPremultipliedXXX 似乎有效。
    【解决方案2】:

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

    --根据 Steven 的评论进行编辑--

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

    【讨论】:

    • 不可能,CGBitmapContextCreate 的宽度参数已经是一个(无符号)整数。铸件已为您完成。
    • 注释报告了一个观察结果,因此根据定义,这不是不可能的,因为它已经发生了。话虽如此,我的分析并不完整。我已经编辑了我的回复并澄清了为什么使用小数宽度是一个问题。
    • 没错,我在质疑观察/测量。感谢您的澄清。顺便说一句,如果您使用 NULL 作为数据参数(如 OP),您还可以为每行的字节数传递 0,以便系统可以选择正确(甚至可能更高性能)的值。
    【解决方案3】:
        CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
    
        CGBitmapInfo    bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little;
    
        CGContextRef theContext = CGBitmapContextCreate(NULL, imgSize.width, imgSize.height, 8, 4*imgSize.width, colorSpace, bitmapInfo);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-21
      • 1970-01-01
      • 1970-01-01
      • 2014-04-03
      • 1970-01-01
      • 2020-10-24
      相关资源
      最近更新 更多