【问题标题】:UIImage with transparent rounded corners带有透明圆角的 UIImage
【发布时间】:2011-06-20 14:52:24
【问题描述】:

我正在使用以下代码向我的 UIImage 添加圆角,但问题是圆角显示“白色”区域而不是透明或“清晰”。我在这里做错了什么:

- (UIImage *)makeRoundCornerImageWithCornerWidth:(int)cornerWidth cornerHeight:(int)cornerHeight {
    UIImage * newImage = nil;

    if (self != nil)    {
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
        int w = self.size.width;
        int h = self.size.height;

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

        CGContextBeginPath(context);
        CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
        [self addRoundedRectToPath:context rect:rect width:cornerWidth height:cornerHeight];

        CGContextClosePath(context);
        CGContextClip(context);

        CGContextDrawImage(context, CGRectMake(0, 0, w, h), self.CGImage);
        CGImageRef imageMasked = CGBitmapContextCreateImage(context);
        CGContextRelease(context);
        CGColorSpaceRelease(colorSpace);

        newImage = [[UIImage imageWithCGImage:imageMasked] retain];
        CGImageRelease(imageMasked);

        [pool release];
    }

    return [newImage autorelease];
}


- (void)addRoundedRectToPath:(CGContextRef)context rect:(CGRect)rect width:(float)ovalWidth height:(float)ovalHeight {
    float fw, fh;

    // If the width or height of the corner oval is zero, then it reduces to a right angle,
    // so instead of a rounded rectangle we have an ordinary one.
    if (ovalWidth == 0 || ovalHeight == 0) {
        CGContextAddRect(context, rect);
        return;
    }

    //  Save the context's state so that the translate and scale can be undone with a call
    //  to CGContextRestoreGState.
    CGContextSaveGState(context);

    //  Translate the origin of the contex to the lower left corner of the rectangle.
    CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect));

    //Normalize the scale of the context so that the width and height of the arcs are 1.0
    CGContextScaleCTM (context, ovalWidth, ovalHeight);

    // Calculate the width and height of the rectangle in the new coordinate system.
    fw = CGRectGetWidth (rect) / ovalWidth;
    fh = CGRectGetHeight (rect) / ovalHeight;

    // CGContextAddArcToPoint adds an arc of a circle to the context's path (creating the rounded
    // corners).  It also adds a line from the path's last point to the begining of the arc, making
    // the sides of the rectangle.
    CGContextMoveToPoint(context, fw, fh/2);                // Start at lower right corner
    CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1);   // Top right corner
    CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1);     // Top left corner
    CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1);      // Lower left corner
    CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1);    // Back to lower right

    // Close the path
    CGContextClosePath(context);

    // Restore the context's state. This removes the translation and scaling
    // but leaves the path, since the path is not part of the graphics state.
    CGContextRestoreGState(context);
}

【问题讨论】:

  • 为什么不将“cornerRadius”添加到视图层并将masksToBounds 设置为YES...应该显示圆角...
  • 这篇文章非常值得阅读,附代码 - vocaro.com/trevor/blog/2009/10/12/…
  • @lukya,是的,我可以,而且我有,但我只是想用这段代码检查问题。

标签: iphone uiimage rounded-corners


【解决方案1】:

在创建位图上下文后立即清除它:

CGContextClearRect (context, CGRectMake(0, 0, w, h));

【讨论】:

    【解决方案2】:

    lukya 在您的问题下方的评论是您可能想要做的。

    确保您导入 QuartzCore:

    #import <QuartzCore/QuartzCore.h>
    

    然后,如果您有一个想要圆角的图像的 UIImageView,只需调用(假设 imageView 是一个属性,cornerRadius 是所需的圆角半径):

    self.imageView.layer.cornerRadius = cornerRadius;
    self.imageView.clipsToBounds = YES;
    

    既然你已经有了self.CGImage,你可以这样做来创建一个UIImageView:

    UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageWithCGImage:self.CGImage]];
    

    只需确保在将 imageView 添加为子视图后释放它即可。

    【讨论】:

      【解决方案3】:

      这是一个使用 UIKit 调用的更简单的公式:

      - (UIImage*) roundCorneredImage: (UIImage*) orig radius:(CGFloat) r {
          UIGraphicsBeginImageContextWithOptions(orig.size, NO, 0);
          [[UIBezierPath bezierPathWithRoundedRect:(CGRect){CGPointZero, orig.size} 
                                      cornerRadius:r] addClip];
          [orig drawInRect:(CGRect){CGPointZero, orig.size}];
          UIImage* result = UIGraphicsGetImageFromCurrentImageContext();
          UIGraphicsEndImageContext();
          return result;
      }
      

      注意 NO 参数 - 这使图像上下文透明,因此剪切区域是透明的。

      【讨论】:

        【解决方案4】:

        https://github.com/detroit-labs/AmazeKit

        听起来像是图书馆的工作

        【讨论】:

          【解决方案5】:
          profileImageView.layer.cornerRadius = profileImageView.frame.size.height/2;
          profileImageView.clipsToBounds = YES;
          

          【讨论】:

          • 不只是发布裸代码,如果您添加一些解释为什么您的解决方案是最好的,或者它如何解决问题,这将有所帮助。
          猜你喜欢
          • 2012-12-17
          • 2022-01-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-26
          • 2013-02-08
          相关资源
          最近更新 更多