iPhone SDK - <error>:CGBitmapContextCreate:不支持的色彩空间</error>

时间:2012-01-09 19:46:27

标签: iphone objective-c

我能够找到一种方法来帮助我修改我的应用程序中UIImage中像素的alpha值,但我遇到了两个错误(第二个肯定是由第一个引起的)。但是,我无法弄清楚发生了什么。

我的方法:

- (void)modifyAlpha:(int)x and:(int)y {

    CGContextRef ctx; 
    CGImageRef imageRef = [scratchOffImage CGImage];
    NSUInteger width = CGImageGetWidth(imageRef);
    NSUInteger height = CGImageGetHeight(imageRef);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    unsigned char *rawData = malloc(height * width * 4);
    NSUInteger bytesPerPixel = 4;
    NSUInteger bytesPerRow = bytesPerPixel * width;
    NSUInteger bitsPerComponent = 8;
    CGContextRef context = CGBitmapContextCreate(rawData, width, height,
                                                 bitsPerComponent, bytesPerRow, colorSpace,
                                                 kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(colorSpace);

    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
    CGContextRelease(context);

    // Now your rawData contains the image data in the RGBA8888 pixel format.
    int byteIndex = (bytesPerRow * y) + x * bytesPerPixel;

    rawData[byteIndex+3] = (char) (255); //Change the pixel value
    ctx = CGBitmapContextCreate(rawData,  
                                CGImageGetWidth( imageRef ),  
                                CGImageGetHeight( imageRef ),  
                                8,  
                                CGImageGetBytesPerRow( imageRef ),  
                                CGImageGetColorSpace( imageRef ),  
                                kCGImageAlphaPremultipliedFirst ); //This line causes an error: incorrect colorspace

    imageRef = CGBitmapContextCreateImage (ctx);  
    UIImage* rawImage = [UIImage imageWithCGImage:imageRef];  

    CGContextRelease(ctx);  

    scratchOffImage = rawImage;  
    [scratchOffImageView setImage:scratchOffImage];

    free(rawData);

}

错误:

<Error>: CGBitmapContextCreate: unsupported color space.

正在抛弃:

ctx = CGBitmapContextCreate(rawData,  ...

然后是第二个错误:

<Error>: CGBitmapContextCreateImage: invalid context 0x0

正在抛弃:

imageRef = CGBitmapContextCreateImage (ctx);

我的图片包含在我最初制作的图片包中,输出Photoshop的Save for Web功能,使用PNG-8作为格式。

当我运行首次使用该函数的示例代码时,示例图像工作正常。但是,我的形象没有。我该怎么调试呢?

有谁知道如何调试这个?我的输入PNG可能格式不正确吗?我该如何查看?

干杯, 布雷特

编辑1:原始源代码来自找到的here示例。该示例显示转换为灰度,而我只需要更改alpha值。

编辑2:我尝试将图像保存为PNG-8和PNG-24,两者都没有运气。

1 个答案:

答案 0 :(得分:2)

PNG-8使用8位索引颜色空间。 Quartz不支持CGBitmapContext的索引颜色空间。 CGBitmapContextCreate documentation表示“请注意,位图图形上下文不支持索引颜色空间。”

您希望传递第一次调用中使用的相同颜色空间(CGImageGetColorSpace( imageRef )变量),而不是将CGBitmapContextCreate作为第二次调用中的颜色空间传递给colorSpace

无论如何,没有理由甚至创建第二个CGBitmapContext。而你正在泄漏CGBitmapContextCreateImage的结果。就这样做:

- (void)modifyAlpha:(int)x and:(int)y {

    CGImageRef imageRef = [scratchOffImage CGImage];
    NSUInteger width = CGImageGetWidth(imageRef);
    NSUInteger height = CGImageGetHeight(imageRef);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    unsigned char *rawData = malloc(height * width * 4);
    NSUInteger bytesPerPixel = 4;
    NSUInteger bytesPerRow = bytesPerPixel * width;
    NSUInteger bitsPerComponent = 8;
    CGContextRef context = CGBitmapContextCreate(rawData, width, height,
                                                 bitsPerComponent, bytesPerRow, colorSpace,
                                                 kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(colorSpace);

    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);

    // Now your rawData contains the image data in the RGBA8888 pixel format.
    int byteIndex = (bytesPerRow * y) + x * bytesPerPixel;

    rawData[byteIndex+3] = (char) (255); //Change the pixel value
    imageRef = CGBitmapContextCreateImage (context);  
    CGContextRelease(context);  

    UIImage* rawImage = [UIImage imageWithCGImage:imageRef];  

    CGImageRelease(imageRef);

    scratchOffImage = rawImage;  
    [scratchOffImageView setImage:scratchOffImage];

    free(rawData);

}