CGImageCreateWithMaskingColors возвращает значение null

У меня есть представление с черным текстом, вокруг которого я хочу создать белое «свечение». Я полагаю, что могу сделать это, сделав снимок экрана, инвертируя цвета (это только черный и белый), замаскировав черный до прозрачного, а затем «подергивая» получившееся изображение в каждом направлении. Когда я пытаюсь замаскировать черный цвет с помощью CGImageCreateWithMaskingColors, я получаю нулевое значение CGImageRef. Пока это то, что у меня есть.

//First get a screenshot into a CI image so I can apply a CI Filter
UIGraphicsBeginImageContext(self.view.frame.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[self.view.layer renderInContext:context];
CIImage* ciImage = [[CIImage alloc] initWithCGImage:[UIGraphicsGetImageFromCurrentImageContext() CGImage]];
UIGraphicsEndImageContext();

//Now apply the CIColorInvert filter
CIFilter* filter = [CIFilter filterWithName:@"CIColorInvert" keysAndValues:kCIInputImageKey, ciImage, nil];
ciImage = [filter valueForKey:kCIOutputImageKey];

//Now I need to get a CG image from the CI image.
CIContext* ciContext = [CIContext contextWithOptions:nil];
CGImageRef ref = [ciContext createCGImage:ciImage fromRect:[ciImage extent]];

//Now I try to mask black
const float maskingColor[6] = {0,0,0,0,0,0};
ref = CGImageCreateWithMaskingColors(ref, maskingColor); //ref is (null)

Я знаю, что альфа-каналы могут испортить работу, но я действительно не думаю, что у меня здесь есть альфа-каналы. Просто чтобы проверить, я сделал CGImageGetColorSpace(ref) и получил kCGColorSpaceDeviceRGB, без альфа-канала.

Может кто-нибудь подскажет, где я ошибаюсь? При желании был бы замечателен быстрый комментарий, который поможет мне понять различия между UIImage, CIImage и CGImage.


person user2320861    schedule 17.02.2014    source источник


Ответы (2)


В документации для CGImageCreateWithMaskingColors параметр image описывается как:

Изображение, которое нужно замаскировать. Этот параметр может не быть маской изображения, может еще не иметь связанной с ним маски изображения или маскирующего цвета, а также не может иметь альфа-компонент.

Вы должны использовать CGImageGetAlphaInfo, чтобы определить, есть ли у вашего CGImageRef альфа-канал.

И с точки зрения избавления от этого надоедливого альфа-канала, я думаю, вы найдете этот ТАК вопрос полезным:

CGBitmapContextCreate с помощью kCGImageAlphaNone

person Rob Jones    schedule 17.02.2014
comment
Спасибо, CGImageGetAlphaInfo(ref) вернул 1. Затем я попробовал const CGFloat maskingColor[8] = {0,0,0,0,0,0,0,0};, но все равно получаю (null). - person user2320861; 17.02.2014
comment
Это kCGImageAlphaPremultipliedLast, что означает, что у вас есть альфа-канал. - person Rob Jones; 17.02.2014
comment
Смотрите мои правки выше. Этот альфа-канал определенно доставит вам некоторые проблемы. - person Rob Jones; 17.02.2014

Вот мое решение, может быть лучший способ сделать это, но это работает!

- (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;
}
person Nick    schedule 28.10.2014
comment
это не работает Я пытаюсь изменить серый пиксель на синий пиксель, как мне добиться с помощью вашего кода - person Rahul Vyas; 30.09.2016