2012-05-29 4 views
9

Я новичок в Quartz. У меня есть 2 изображения, фон и маска с формой выреза, которую я хочу заложить на фоне, чтобы вырезать секцию. Полученное изображение должно быть формой выреза. Это моя маска (форма в среднем составляет 0 альфа):CGContextClipToMask возвращает пустое изображение

image mask

И это мой код:

UIView *canvas = [[[sender superview] subviews] objectAtIndex:0]; 

UIGraphicsBeginImageContext(canvas.bounds.size); 
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB(); 
CGContextRef cgContext = CGBitmapContextCreate(NULL, canvas.bounds.size.width, canvas.bounds.size.height, 8, 0, colourSpace, kCGImageAlphaPremultipliedLast); 
CGColorSpaceRelease(colourSpace); 

CGImageRef maskImage = [[UIImage imageNamed:@"Mask.png"] CGImage]; 
CGContextClipToMask(cgContext, CGRectMake(0, 0, canvas.frame.size.width, canvas.frame.size.height), maskImage); 

CGImageRef maskedImageRef = CGBitmapContextCreateImage(cgContext); 
CGContextRelease(cgContext); 

UIImage *maskedImage = [UIImage imageWithCGImage:maskedImageRef]; 
UIGraphicsEndImageContext(); 

[button setBackgroundImage:maskedImage forState:UIControlStateNormal]; 

За исключением ничего не появляется ... Любая идея, где я собираюсь неправильно? Большое спасибо.

+0

Вы не кажется, что-то рисуют. Вы ничего не выталкиваете из ничего и ничего не получаете. Как и ожидалось. Между отсечением для маскировки и созданием изображения вы должны нарисовать что-то. –

ответ

10

После того как вы кликнули контекст с маской, вы должны нарисовать что-то в этом контексте.

Кроме того:

  • вы должны использовать UIGraphicsBeginImageContextWithOptions для поддержки масштабного коэффициента.
  • Вы создаете два контекста: один с UIGraphicsBeginImageContext, а другой с CGBitmapContextCreate. Одного достаточно :)
  • вам следует «перевернуть» альфу вашей маски, потому что согласно документам The source samples of mask determine which points of the clipping area are changed. Другими словами прозрачные станут прозрачной

Простой пример кода, где я клип изображение в ImageView, а затем установить его обратно:

UIGraphicsBeginImageContextWithOptions(self.imageView.frame.size, NO, 0.0); 
CGContextRef context = UIGraphicsGetCurrentContext(); 

CGContextTranslateCTM(context, 0.0, self.imageView.frame.size.height); 
CGContextScaleCTM(context, 1.0, -1.0); 

CGImageRef maskImage = [[UIImage imageNamed:@"mask.png"] CGImage]; 
CGContextClipToMask(context, self.imageView.bounds, maskImage); 

CGContextTranslateCTM(context, 0.0, self.imageView.frame.size.height); 
CGContextScaleCTM(context, 1.0, -1.0); 

[[self.imageView image] drawInRect:self.imageView.bounds]; 

UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 

self.imageView.image = image; 

Пример использования CGImageCreateWithMask:

UIImage *image = [UIImage imageNamed:@"image"]; 

CGImageRef originalMask = [UIImage imageNamed:@"mask"].CGImage; 
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(originalMask), 
            CGImageGetHeight(originalMask), 
            CGImageGetBitsPerComponent(originalMask), 
            CGImageGetBitsPerPixel(originalMask), 
            CGImageGetBytesPerRow(originalMask), 
            CGImageGetDataProvider(originalMask), nil, YES); 

CGImageRef maskedImageRef = CGImageCreateWithMask(image.CGImage, mask); 

UIImage *maskedImage = [UIImage imageWithCGImage:maskedImageRef scale:image.scale orientation:image.imageOrientation]; 

CGImageRelease(mask); 
CGImageRelease(maskedImageRef); 
+0

Я вижу, спасибо! Всего пару вопросов. Зачем вам нужно дважды переводить SwitchCTM? Кроме того, я получаю обратный эффект - часть альфа-0 маски вырезается, тогда как черная часть изображения рисуется. Согласно документам, мне нужно замаскировать изображение с изображением, а не с помощью маски, используя CGImageCreateWithMask, но где я могу это использовать? – Smikey

+0

UIKit и CGGraphics имеют разные системы координат, поэтому нам нужно перевести матрицу. «Откроется альфа-часть маски» - это именно то, о чем говорит документация для 'CGContextClipToMask' и' CGImageCreateWithMask'. Добавлен пример 'CGImageCreateWithMask'. –

+0

К сожалению, не из решений, которые сейчас работают в ios 11, когда я тестировал, я пытался замаскировать два UIImages и использовал оба этих метода. первый сжимает изображение после отсечения, а второй возвращает {0.0} @ Евгения Шуракова –