CGImageCreateWithMaskingColors не работает с iOS7

Я разработал приложение на iOS5 и iOS6. После обновления до XCode 5 и iOS7 у меня появилось несколько новых ошибок.

Основным является colorMasking, больше не работает. Точно такой же код все еще компилируется и работает на телефоне с iOS6. На iOS7 маскированный цвет все еще там. Я пытался найти ответ в Google, но не нашел ответа. Это ошибка 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;
}

Вот пара сообщений Stackru, которые я обнаружил, которые помогли мне начать работать в iOS6: прозрачность iOS Цвет от iOS до прозрачного в UIImage

2 ответа

Решение

Я наткнулся на какое-то странное поведение CGImageCreateWithMaskingColors в сочетании с UIImagePNGRepresentation, Это может или не может быть связано с вашей проблемой. Я обнаружил, что если:

  1. Если использовать CGImageCreateWithMaskingColors и немедленно добавьте это изображение в представление изображения, я вижу, что прозрачность, кажется, была применена правильно;

  2. Но в iOS 7, если я тогда:

    • взять это изображение из CGImageCreateWithMaskingColors и создать NSData с помощью UIImagePNGRepresentation; а также

    • если перезагрузить изображение из этого NSData с помощью imageWithDataтогда полученное изображение больше не будет иметь прозрачности.

    Чтобы подтвердить это, если я writeToFile за это NSData и проверить сохраненное изображение в таком инструменте, как Photoshop, я могу подтвердить, что к файлу не применена прозрачность.

    Это проявляется только в iOS 7. В iOS 6 это нормально.

  3. Но если я возьму изображение на шаге 1 и поверну его через drawInRectТот же процесс сохранения изображения и последующей его загрузки работает нормально.

Следующий код иллюстрирует проблему:

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

Я загружал JPEG, который по какой-то причине загружается с альфа-каналом, который не работает при маскировании, поэтому здесь я воссоздаю 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;
}
Другие вопросы по тегам