3

Have a imageViewA (frame{0,0,320,200}) in my app, and I want to clip a circle with the imageViewA's center, radius=50, and draw into another imageViewB (frame{0,0,100,100}); the original image effect like this :

enter image description here

and use below code to clip:

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];
}

clip image effect like this:

enter image description here

I only need the circle view, but the clip effect display that imageViewB has white space. How to clip this image correctly? Thanks!

Roby
  • 179
  • 2
  • 14

4 Answers4

6
imageViewB.layer.cornerRadius = 50.0;
imageViewB.layer.masksToBounds = YES;
Hafthor
  • 16,358
  • 9
  • 56
  • 65
2

JPEG doesn't support transparency. Use UIImagePNGRepresentation instead of UIImageJPEGRepresentation, and you will have the result you want.

NSData *imageData = UIImagePNGRepresentation(newImage);
if([imageData writeToFile:headerPath atomically:YES]){
    imageViewB.image = [UIImage imageWithContentsOfFile:headerPath];
}
Emmanuel
  • 2,897
  • 1
  • 14
  • 15
  • Yes! Use UIImagePNGRepresentation instead of UIImageJPEGRepresentation, the effect is correctly. But the clipped circle view not fill imageViewB. And I have set the imageViewB.contentMode = UIViewContentModeScaleAspectFill. Why? – Roby Nov 08 '13 at 02:05
  • @user2082720 who is "self" in you code ? imageViewA ? I think that you don't use correct size for your purpose. – Emmanuel Nov 08 '13 at 09:54
0

Just use masking for this purposes This code will help you to mask images

+ (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;
}

This article can help you http://www.abdus.me/ios-programming-tips/how-to-mask-image-in-ios-an-image-masking-technique/

After masking you need to create an imageView with that masked image and then subview it into another imageView.

l0gg3r
  • 8,864
  • 3
  • 26
  • 46
0

Before you draw the image:

CGContextSetBlendMode(ctx, kCGBlendModeClear);
CGContextFillRect(ctx, self.bounds);
CGContextSetBlendMode(ctx, kCGBlendModeNormal);
manta
  • 369
  • 1
  • 9