使用 CGContextClip 用图像剪辑一个圆圈

Posted

技术标签:

【中文标题】使用 CGContextClip 用图像剪辑一个圆圈【英文标题】:Use CGContextClip to clip a circle with image 【发布时间】:2013-11-07 10:16:15 【问题描述】:

在我的应用中有一个 imageViewA (frame0,0,320,200),我想以 imageViewA 的中心,radius=50 裁剪一个圆,然后绘制到另一个 imageViewB (frame0,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有空白的剪辑效果显示。 如何正确剪辑此图像? 谢谢!

【问题讨论】:

【参考方案1】:
imageViewB.layer.cornerRadius = 50.0;
imageViewB.layer.masksToBounds = YES;

【讨论】:

【参考方案2】:

JPEG 不支持透明度。使用UIImagePNGRepresentation 而不是UIImageJPEGRepresentation,你会得到你想要的结果。

NSData *imageData = UIImagePNGRepresentation(newImage);
if([imageData writeToFile:headerPath atomically:YES])
    imageViewB.image = [UIImage imageWithContentsOfFile:headerPath];

【讨论】:

是的!使用UIImagePNGRepresentation代替UIImageJPEGRepresentation,效果正确。但是裁剪的圆形视图没有填充 imageViewB。我已经设置了 imageViewB.contentMode = UIViewContentModeScaleAspectFill。为什么? @user2082720 在你的代码中谁是“自我”?图像视图A?我认为您没有为您的目的使用正确的尺寸。【参考方案3】:

只需为此目的使用遮罩 此代码将帮助您屏蔽图像

+ (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 然后将其 subview 到另一个 imageView 中。

【讨论】:

你能告诉我你的邮箱吗?【参考方案4】:

在绘制图像之前:

CGContextSetBlendMode(ctx, kCGBlendModeClear);
CGContextFillRect(ctx, self.bounds);
CGContextSetBlendMode(ctx, kCGBlendModeNormal);

【讨论】:

以上是关于使用 CGContextClip 用图像剪辑一个圆圈的主要内容,如果未能解决你的问题,请参考以下文章

带有形状的 WPF 剪辑

iOS:CoreGraphics - 使用 CGContextClip 和 lineCap = .Round 剪裁弧线

javascript - 如何使用 drawImage/putImageData 进行剪辑

CGContextClip 抗锯齿问题

可组合成内容形状的剪辑

如何剪辑图像或剪切不需要的部分?