Ответ 1
Если я правильно понимаю, вы хотите создать UIImage из слоя UIView, в то время как этот слой замаскирован. Я предполагаю, что вы хотите, чтобы целевой UIImage имел прозрачный фон.
У меня не было проблем с этим, и у меня есть демонстрационный проект, на который вы можете взглянуть:
https://bitbucket.org/reydan/so_imagemask
Сначала вам нужно нажать кнопку Маска. Он загрузит изображение маски (черно-белое) из пакета и установит его как маску слоя для контейнера UIView выше.
Затем вы можете нажать кнопку Копировать изображение, которая отображает контейнер UIView в UIImage, а затем установите его в изображение целевого изображения ниже, чтобы увидеть результат.
Я также опубликую здесь 2 метода:
- (IBAction)onMask:(id)sender {
UIImage* maskImage = [UIImage imageNamed:@"star.png"];
UIImageView* maskImageView = [[UIImageView alloc] initWithImage:maskImage];
maskImageView.contentMode = UIViewContentModeScaleAspectFit;
maskImageView.frame = _mainContainerView.bounds;
_mainContainerView.layer.mask = maskImageView.layer;
}
- (IBAction)onCopyImage:(id)sender {
UIGraphicsBeginImageContextWithOptions(_mainContainerView.bounds.size, FALSE, [[UIScreen mainScreen] scale]);
[_mainContainerView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
_destImageView.image = img;
}
ИЗМЕНИТЬ
По-видимому, renderInContext:
на IOS6 не использует маску (как сказано здесь и на SO).
Мое решение состояло в том, чтобы вручную применить маску к изображению. Маска берется из свойства маски слоя и визуализируется в контексте, поэтому у нас нет проблем с преобразованиями /contentModes/etc.
Вот обновленный исходный код (он также доступен на битбакете):
- (IBAction)onCopyImage:(id)sender {
// Get the image from the mainImageView
UIGraphicsBeginImageContextWithOptions(_mainContainerView.bounds.size, FALSE, [[UIScreen mainScreen] scale]);
[_mainContainerView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Use the next block if targeting IOS6
{
// Manually create a mask image (taken from the mask layer)
UIGraphicsBeginImageContextWithOptions(_mainContainerView.bounds.size, TRUE, [[UIScreen mainScreen] scale]);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(ctx, [UIColor whiteColor].CGColor);
CGContextFillRect(ctx, _mainContainerView.bounds);
[_mainContainerView.layer.mask renderInContext:ctx];
UIImage * maskimg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Create a image mask from the UIImage
CGImageRef maskRef = maskimg.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);
// Apply the mask to our source image
CGImageRef maskedimg= CGImageCreateWithMask(img.CGImage, mask);
// Convert to UIImage so we can easily display it in a UIImageView
img = [UIImage imageWithCGImage:maskedimg scale:img.scale orientation:img.imageOrientation];
CGImageRelease(mask);
CGImageRelease(maskedimg);
}
_destImageView.image = img;
}
ИЗМЕНИТЬ Пожалуйста, проверьте последний проект на битбакете, поскольку он содержит последнюю версию.