简体   繁体   English

CGImageCreateWithMaskingColors不适用于iOS7

[英]CGImageCreateWithMaskingColors Doesn't Work with iOS7

I've developed an app on iOS5 and iOS6. 我在iOS5和iOS6上开发了一个应用程序。 After I upgraded to XCode 5 and iOS7, I have some new bugs to play with. 在我升级到XCode 5和iOS7后,我有一些新的bug。

The main one is the colorMasking no longer works. 主要的是colorMasking不再有效。 The exact same code still compiles and works on a phone with iOS6. 完全相同的代码仍可编译并适用于iOS6手机。 On iOS7, the masked color is still there. 在iOS7上,蒙面颜色仍然存在。 I tried to find the answer on Google, but haven't found an answer. 我试图在谷歌上找到答案,但还没找到答案。 Is it a bug of iOS7, or does anybody know of a better way of doing colormasking? 这是iOS7的错误,还是有人知道更好的做彩色掩模的方法?

Here is the code: 这是代码:

- (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;
}

Here are a couple StackOverflow posts I found that helped me get it working in iOS6 the first place: Transparency iOS iOS color to transparent in UIImage 以下是我发现的几个StackOverflow帖子,帮助我在iOS6中首先使用它: 透明度iOS iOS颜色在UIImage中透明

I have stumbled across some strange behavior of CGImageCreateWithMaskingColors in conjunction with UIImagePNGRepresentation . 我偶然发现了CGImageCreateWithMaskingColors一些奇怪行为以及UIImagePNGRepresentation This may or may not be related to your problem. 这可能与您的问题有关,也可能与您无关。 I have found that if: 我发现如果:

  1. If use CGImageCreateWithMaskingColors and immediately add that image to an image view, I can see that the transparency appears to have been applied correctly; 如果使用CGImageCreateWithMaskingColors并立即将该图像添加到图像视图,我可以看到透明度似乎已正确应用;

  2. But in iOS 7, if I then: 但是在iOS 7中,如果我那么:

    • take this image from CGImageCreateWithMaskingColors and create a NSData using UIImagePNGRepresentation ; CGImageCreateWithMaskingColors获取此图像,并使用UIImagePNGRepresentation创建NSData ; and

    • if reload the image from that NSData using imageWithData , then the resulting image will no longer have its transparency. 如果使用imageWithData从该NSData重新加载图像,则生成的图像将不再具有透明度。

    To confirm this, if I writeToFile for this NSData and examine the saved image in a tool like Photoshop, I can confirm that the file does not have any transparency applied. 要确认这一点,如果我为此NSData writeToFile文件并在Photoshop等工具中检查了保存的图像,我可以确认该文件没有应用任何透明度。

    This only manifests itself in iOS 7. In iOS 6 it's fine. 这仅在iOS 7中体现出来。在iOS 6中它很好。

  3. But if I take the image in step 1 and roundtrip it through drawInRect , the same process of saving the image and subsequently loading it works fine. 但是,如果我在步骤1中拍摄图像并通过drawInRect往返,则保存图像并随后加载图像的过程相同。

This following code illustrates the issue: 以下代码说明了此问题:

- (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;
}

I was loading a JPEG which for some reason loads with an alpha channel, which won't work when masking, so here I recreate the CGImage ignoring the alpha channel. 我正在加载一个JPEG,由于某种原因加载了alpha通道,这在遮罩时不起作用,所以在这里我重新创建忽略alpha通道的CGImage。 There may be a better way of doing this but this works! 可能有更好的方法,但这有效!

- (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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM