Используйте CGContextClip, чтобы обрезать круг изображением

У меня есть imageViewA (кадр {0,0,320,200}) в моем приложении, и я хочу обрезать круг с центром imageViewA, радиус = 50 и рисовать в другом imageViewB (кадр {0,0,100,100}); исходный эффект изображения выглядит следующим образом:

введите здесь описание изображения

и используйте приведенный ниже код для обрезки:

UIGraphicsBeginImageContext(self.frame.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGFloat height = self.bounds.size.height;
CGContextTranslateCTM(ctx, 0.0, height);
CGContextScaleCTM(ctx, 1.0, -1.0);
CGContextAddArc(ctx, self.frame.size.width/2, self.frame.size.height/2, 50, 0, 2*M_PI, 0);
CGContextClosePath(ctx);
CGContextSaveGState(ctx);
CGContextClip(ctx);
CGContextDrawImage(ctx, CGRectMake(0,0,self.frame.size.width, self.frame.size.height), image.CGImage);
CGContextRestoreGState(ctx);
CGImageRef imageRef = CGBitmapContextCreateImage (ctx);
UIImage *newImage = [UIImage imageWithCGImage:imageRef];
NSString *headerPath = [NSString stringWithFormat:@"%@/header.png",HomeDirectory];
NSData *imageData = UIImageJPEGRepresentation(newImage, 1.0);
if([imageData writeToFile:headerPath atomically:YES]){
    imageViewB.image = [UIImage imageWithContentsOfFile:headerPath];
}

клип эффект изображения, как это:

введите здесь описание изображения

Мне нужен только вид круга, но эффект клипа показывает, что imageViewB имеет пустое пространство. Как правильно обрезать это изображение? Спасибо!


person Roby    schedule 07.11.2013    source источник


Ответы (3)


JPEG не поддерживает прозрачность. Используйте UIImagePNGRepresentation вместо UIImageJPEGRepresentation, и вы получите желаемый результат.

NSData *imageData = UIImagePNGRepresentation(newImage);
if([imageData writeToFile:headerPath atomically:YES]){
    imageViewB.image = [UIImage imageWithContentsOfFile:headerPath];
}
person Emmanuel    schedule 07.11.2013
comment
Да! Используйте UIImagePNGRepresentation вместо UIImageJPEGRepresentation, эффект правильный. Но вид обрезанного круга не заполняет imageViewB. И я установил imageViewB.contentMode = UIViewContentModeScaleAspectFill. Почему? - person Roby; 08.11.2013
comment
@user2082720 user2082720 кто в твоем коде есть я? изображениеВидА ? Я думаю, что вы не используете правильный размер для своей цели. - person Emmanuel; 08.11.2013

Просто используйте маскирование для этих целей. Этот код поможет вам маскировать изображения

+ (UIImage *)maskImage:(UIImage *)image withMask:(UIImage *)maskImage
{
    CGImageRef maskRef = maskImage.CGImage;
    CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
                                        CGImageGetHeight(maskRef),
                                        CGImageGetBitsPerComponent(maskRef),
                                        CGImageGetBitsPerPixel(maskRef),
                                        CGImageGetBytesPerRow(maskRef),
                                        CGImageGetDataProvider(maskRef), NULL, false);

    CGImageRef masked = CGImageCreateWithMask([image CGImage], mask);
    UIImage *uiMasked = [UIImage imageWithCGImage:masked];
    CFRelease(mask);
    CFRelease(masked);
    return uiMasked;
}

Эта статья может помочь вам http://www.abdus.me/ios-programming-tips/how-to-mask-image-in-ios-an-image-masking-technique/

После маскирования вам нужно создать imageView с этим замаскированным изображением, а затем просмотреть его в другом imageView.

person l0gg3r    schedule 07.11.2013
comment
Можете ли вы сказать мне свой адрес электронной почты? - person Roby; 08.11.2013

Прежде чем рисовать изображение:

CGContextSetBlendMode(ctx, kCGBlendModeClear);
CGContextFillRect(ctx, self.bounds);
CGContextSetBlendMode(ctx, kCGBlendModeNormal);
person manta    schedule 19.05.2014