CGImageCreateWithMaskingColors不适用于iOS7

时间:2013-10-01 05:12:30

标签: ios objective-c uiimage ios7

我在iOS5和iOS6上开发了一个应用程序。在我升级到XCode 5和iOS7后,我有一些新的bug。

主要的一个是colorMasking不再有效。完全相同的代码仍可编译并适用于iOS6手机。在iOS7上,蒙面颜色仍然存在。我试图在谷歌上找到答案,但还没找到答案。这是iOS7的错误,还是有人知道更好的做彩色掩模的方法吗?

以下是代码:

- (UIImage*) processImage :(UIImage*) image
{
    UIImage *inputImage = [UIImage imageWithData:UIImageJPEGRepresentation(image, 1.0)];
    const float colorMasking[6]={100.0, 255.0, 0.0, 100.0, 100.0, 255.0};
    CGImageRef imageRef = CGImageCreateWithMaskingColors(inputImage.CGImage, colorMasking);
    UIImage* finalImage = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    return finalImage;
}

以下是我发现的几个StackOverflow帖子,帮助我在iOS6中首先使用它: Transparency iOS iOS color to transparent in UIImage

2 个答案:

答案 0 :(得分:8)

我偶然发现了CGImageCreateWithMaskingColorsUIImagePNGRepresentation一起的一些奇怪行为。这可能与您的问题有关,也可能与您无关。我发现如果:

  1. 如果使用CGImageCreateWithMaskingColors并立即将该图片添加到图片视图,我可以看到透明度似乎已正确应用;

  2. 但是在iOS 7中,如果我那么:

    • CGImageCreateWithMaskingColors获取此图片,并使用NSData创建UIImagePNGRepresentation;以及

    • 如果使用NSDataimageWithData重新加载图片,则生成的图片将不再具有透明度。

    要确认这一点,如果我writeToFile为此NSData并在Photoshop等工具中检查保存的图像,我可以确认该文件没有应用任何透明度。

    这只能在iOS 7中体现出来。在iOS 6中它很好。

  3. 但如果我在步骤1中拍摄图像并通过drawInRect往返,则保存图像并随后加载图像的过程相同。

  4. 以下代码说明了问题:

    - (UIImage*) processImage :(UIImage*) inputImage
    {
        const float colorMasking[6] = {255.0, 255.0, 255.0, 255.0, 255.0, 255.0};
        CGImageRef imageRef = CGImageCreateWithMaskingColors(inputImage.CGImage, colorMasking);
        UIImage* finalImage = [UIImage imageWithCGImage:imageRef];
        CGImageRelease(imageRef);
    
        // If I put this image in an image view, I see the transparency fine.
    
        self.imageView.image = finalImage;                           // this works
    
        // But if I save it to disk and the file does _not_ have any transparency
    
        NSString *documentsPath           = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
        NSString *pathWithoutTransparency = [documentsPath stringByAppendingPathComponent:@"image-but-no-transparency.png"];
        NSData   *data                    = UIImagePNGRepresentation(finalImage);
        [data writeToFile:pathWithoutTransparency atomically:YES];   // save it so I can check out the file in Photoshop
    
        // In iOS 7, the following imageview does not honor the transparency
    
        self.imageView2.image = [UIImage imageWithData:data];        // this does not work in iOS 7
    
        // but, if I round-trip the original image through `drawInRect` one final time,
        // the transparency works
    
        UIGraphicsBeginImageContextWithOptions(finalImage.size, NO, 1.0);
        [finalImage drawInRect:CGRectMake(0, 0, finalImage.size.width, finalImage.size.height)];
        UIImage *anotherRendition = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        data = UIImagePNGRepresentation(anotherRendition);
        NSString *pathWithTransparency = [documentsPath stringByAppendingPathComponent:@"image-with-transparancy.png"];
        [data writeToFile:pathWithTransparency atomically:YES];
    
        // But this image is fine
    
        self.imageView3.image = [UIImage imageWithContentsOfFile:pathWithTransparency];   // this does work
    
        return anotherRendition;
    }
    

答案 1 :(得分:0)

我正在加载JPEG,由于某种原因加载了alpha通道,这在遮罩时不起作用,所以在这里我重新创建忽略alpha通道的CGImage。可能有一种更好的方法可以做到这一点,但这有效!

- (UIImage *)imageWithChromaKeyMasking {
    const CGFloat colorMasking[6]={255.0,255.0,255.0,255.0,255.0,255.0};
    CGImageRef oldImage = self.CGImage;
    CGBitmapInfo oldInfo = CGImageGetBitmapInfo(oldImage);
    CGBitmapInfo newInfo = (oldInfo & (UINT32_MAX ^ kCGBitmapAlphaInfoMask)) | kCGImageAlphaNoneSkipLast;
    CGDataProviderRef provider = CGImageGetDataProvider(oldImage);
    CGImageRef newImage = CGImageCreate(self.size.width, self.size.height, CGImageGetBitsPerComponent(oldImage), CGImageGetBitsPerPixel(oldImage), CGImageGetBytesPerRow(oldImage), CGImageGetColorSpace(oldImage), newInfo, provider, NULL, false, kCGRenderingIntentDefault);
    CGDataProviderRelease(provider); provider = NULL;
    CGImageRef im = CGImageCreateWithMaskingColors(newImage, colorMasking);
    UIImage *ret = [UIImage imageWithCGImage:im];
    CGImageRelease(im);
    return ret;
}