简体   繁体   中英

Quartz UIImage with rounded corners and transparent background on iOS

I have used this solution to apply corner radius to UIImage in Quartz . It works fine like I predicted.

However the corners area outside of the image are not transparent but somewhat colored in white:

石英制带圆角的UIImage

The image above shows top left corner of processed image that is opaque and not transparent.

I want cropped-out edges to be totally transparent. How can I achieve this?

EDIT: If I want to do this with UIImageView I would already done this. So please keep in mind that I want to do this with Quartz on UIImage object not UIImageView .

SOLUTION: The problem is actually not in the drawing code but rather in writing that image to the file system. I've saved image as JPEG an not as PNG. That's why corners were not transparent cos JPEG does not have alpha filter.

I usually use a custom category implemented on UIImage to crop the images with round corners. This was taken from this answer.

void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight, BOOL top, BOOL bottom)
{
    float fw, fh;
    if (ovalWidth == 0 || ovalHeight == 0) {
        CGContextAddRect(context, rect);
        return;
    }
    CGContextSaveGState(context);
    CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect));
    CGContextScaleCTM (context, ovalWidth, ovalHeight);
    fw = CGRectGetWidth (rect) / ovalWidth;
    fh = CGRectGetHeight (rect) / ovalHeight;
    CGContextMoveToPoint(context, fw, fh/2);
    CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 0);

    NSLog(@"bottom? %d", bottom);

    if (top) {
        CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 3);
    } else {
        CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 0);
    }

    if (bottom) {
        CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 3);
    } else {
        CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 0);
    }

    CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 0);
    CGContextClosePath(context);
    CGContextRestoreGState(context);
}

- (UIImage *)roundCornersOfImage:(UIImage *)source roundTop:(BOOL)top roundBottom:(BOOL)bottom {
    int w = source.size.width;
    int h = source.size.height;

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);

    CGContextBeginPath(context);
    CGRect rect = CGRectMake(0, 0, w, h);
    addRoundedRectToPath(context, rect, 4, 4, top, bottom);
    CGContextClosePath(context);
    CGContextClip(context);

    CGContextDrawImage(context, CGRectMake(0, 0, w, h), source.CGImage);

    CGImageRef imageMasked = CGBitmapContextCreateImage(context);
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);

    return [UIImage imageWithCGImage:imageMasked];    
}

For transparent use this:

 const float colorMasking[6] = {1.0, 1.0, 0.0, 0.0, 1.0, 1.0};
 yourImage = [UIImage imageWithCGImage: CGImageCreateWithMaskingColors(yourImage.CGImage, colorMasking)];

EDIT : Add this both line in method of UIImage category

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, rect);

add these bellow lines in your drawRect method ..

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextClearRect(context, rect);
    ///your another code here
}

after create Context it required to clear another context from that Rect... so after that line add this line CGContextClearRect(context, rect); .

The problem is actually not in the drawing code but rather in writing that image to the file system. I've saved image as JPEG an not as PNG. That's why corners were not transparent cos JPEG does not have alpha filter.

Just replaced this line of code:

[UIImageJPEGRepresentation(image, 0.75) writeToFile:path atomically:YES];

... with this one:

[UIImagePNGRepresentation(image) writeToFile:path atomically:YES];

Try this code

Image.layer.cornerRadius = 10.0;
Image.layer.borderColor = [UIColor blackColor].CGColor;
Image.layer.borderWidth = 0.5;
Image.clipsToBounds = YES;
Image.backgroundColor = [UIColor clearColor];

Hope it helps you

EDIT :-

I think you just need to add this :-

Image.clipsToBounds = YES;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM