将索引颜色.png转换为RGB或灰度

时间:2017-02-07 14:42:53

标签: ios objective-c cgimage color-space

我正在写这个今日小工具,需要显示图像。 我注意到,每次加载Widget时,都会重新绘制图像。这需要大约半秒钟。 经过一番调查,我发现,罪魁祸首是图像文件在索引颜色空间中。 所以:我的问题是: 如何将此文件转换为iPhone可以更有效地显示的内容?例如,RGB文件。然后我将它保存到一个新文件,并在我的UIImageView中加载该新文件。

我用CGImage玩了一下,因为我相信这是解决方案的方向,但我最终得到了一个白色的UIImageView。

这是我的代码:

UIImage * theCartoon = [UIImage imageWithData:imageData];
    CGImageRef si = [theCartoon CGImage];
    CGDataProviderRef src = CGImageGetDataProvider(si);
    CGImageRef imageRef = CGImageCreateWithPNGDataProvider(src, NULL, NO, kCGRenderingIntentDefault);
    cartoon.image = [[UIImage alloc] initWithCGImage:imageRef];

有关此方法的任何建议吗?一些明显的错误编程?

2 个答案:

答案 0 :(得分:1)

试试这个

// The source image
CGImageRef image = theCartoon.CGImage;
CGSize size = CGSizeMake(CGImageGetWidth(image), CGImageGetHeight(image));

// The result image in RGB color space   
CGImageRef result = nil;

// Check color space
CGColorSpaceRef srcColorSpace = CGImageGetColorSpace(image);
if (CGColorSpaceGetModel(srcColorSpace) != kCGColorSpaceModelRGB) {
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(nil, size.width, size.height, 8, 0, colorSpace, kCGImageAlphaNoneSkipLast);

    CGRect rect = {CGPointZero, size};
    CGContextDrawImage(context, rect, image);
    result = CGBitmapContextCreateImage(context);

    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
}

答案 1 :(得分:0)

问了问题已经有一段时间了,但是对于其他可能需要这个问题的人,这是我的解决方案:

-(UIImage *) convertIndexedColorSpaceToRGB:(UIImage *) sourceImage {

CGImageRef originalImageRef = sourceImage.CGImage;
const CGBitmapInfo originalBitmapInfo = CGImageGetBitmapInfo(originalImageRef);

// See: http://stackoverflow.com/questions/23723564/which-cgimagealphainfo-should-we-use
const uint32_t alphaInfo = (originalBitmapInfo & kCGBitmapAlphaInfoMask);
CGBitmapInfo bitmapInfo = originalBitmapInfo;
switch (alphaInfo)
{
    case kCGImageAlphaNone:
        bitmapInfo |= kCGBitmapByteOrder32Big | kCGImageAlphaNoneSkipLast;
        break;
    case kCGImageAlphaPremultipliedFirst:
    case kCGImageAlphaPremultipliedLast:
    case kCGImageAlphaNoneSkipFirst:
    case kCGImageAlphaNoneSkipLast:
        break;
    case kCGImageAlphaOnly:
    case kCGImageAlphaLast:
    case kCGImageAlphaFirst:
    { 
        return sourceImage;
    }
        break;
}

const CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
const CGSize pixelSize = CGSizeMake(sourceImage.size.width * sourceImage.scale, sourceImage.size.height * sourceImage.scale);

const CGContextRef context = CGBitmapContextCreate(NULL,
                                                   pixelSize.width,
                                                   pixelSize.height,
                                                   CGImageGetBitsPerComponent(originalImageRef),
                                                   pixelSize.width*4,
                                                   colorSpace,
                                                   bitmapInfo
                                                   );

CGColorSpaceRelease(colorSpace);

if (!context) return sourceImage;

const CGRect imageRect = CGRectMake(0, 0, pixelSize.width, pixelSize.height);
UIGraphicsPushContext(context);

// Flip coordinate system. See: http://stackoverflow.com/questions/506622/cgcontextdrawimage-draws-image-upside-down-when-passed-uiimage-cgimage
CGContextTranslateCTM(context, 0, pixelSize.height);
CGContextScaleCTM(context, 1.0, -1.0);
[sourceImage drawInRect:imageRect];
UIGraphicsPopContext();
const CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context);
CGContextRelease(context);
UIImage *image = [UIImage imageWithCGImage:decompressedImageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];
CGImageRelease(decompressedImageRef);

return image; }