【问题标题】:How to round edges of an UIImage?如何圆化 UIImage 的边缘?
【发布时间】:2011-12-08 12:53:38
【问题描述】:

我尝试加快 UITableView 的滚动速度。我通过自己绘制单元格而不是添加子视图来做到这一点。

我想画的东西之一是图像。图像应具有圆形边缘。当我使用子视图绘制单元格时,我将 UIImageView 的图层更改为圆角。

现在我直接绘制 UIImage 并且没有要修改的图层。如何绘制圆边的图像?

【问题讨论】:

    标签: iphone objective-c ios


    【解决方案1】:

    我很确定我是从 stackoverflow 得到这段代码的。

    - (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 sourceImage = [image CGImage];
    CGImageRef imageWithAlpha = sourceImage;
    //add alpha channel for images that don't have one (ie GIF, JPEG, etc...)
    //this however has a computational cost
    // needed to comment out this check. Some images were reporting that they
    // had an alpha channel when they didn't! So we always create the channel.
    // It isn't expected that the wheelin application will be doing this a lot so 
    // the computational cost isn't onerous.
    //if (CGImageGetAlphaInfo(sourceImage) == kCGImageAlphaNone) { 
    imageWithAlpha = CopyImageAndAddAlphaChannel(sourceImage);
    //}
    
    CGImageRef masked = CGImageCreateWithMask(imageWithAlpha, mask);
    CGImageRelease(mask);
    
    //release imageWithAlpha if it was created by CopyImageAndAddAlphaChannel
    if (sourceImage != imageWithAlpha) {
        CGImageRelease(imageWithAlpha);
    }
    
    UIImage* retImage = [UIImage imageWithCGImage:masked];
    CGImageRelease(masked);
    
    return retImage;
    

    }

    我称之为:

        customImage = [customImage maskImage:customImage withMask:[UIImage imageNamed:@"CircularMask.png"]];
    [customImageView setImage:customImage]; 
    

    希望有帮助!

    【讨论】:

      【解决方案2】:

      听起来您只是想从矩形图像中删除角点:通过 CGImage API 创建新图像 - 您将为输入图像应用蒙版。

      【讨论】:

        【解决方案3】:

        你对图片使用缓存吗?

        如果是这样,我建议您在缓存 UIImage 之前将其应用到它,以便在绘制圆角后您可以重复使用该图像。

        这是 UIImage 上的一个类别,您可以使用它来获取圆形 UIImage。

        我可能在某个地方找到了这段代码,所以我提前向原作者道歉,因为我没有给他/她的功劳。

        #import <Foundation/Foundation.h>
        
        @interface UIImage (DPRounded)
        - (UIImage *)imageWithCornerRadius:(CGFloat)radius;
        @end
        
        
        @implementation UIImage (DPRounded)
        
        static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight)
        {
            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, 1);
            CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1);
            CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1);
            CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1);
            CGContextClosePath(context);
            CGContextRestoreGState(context);
        }
        
        - (UIImage *)imageWithCornerRadius:(CGFloat)radius
        {
            UIImage * newImage = nil;
        
            if(self != nil)
            {
                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);
                addRoundedRectToPath(context, rect, radius, radius);
                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);
            }
        
            return [newImage autorelease];
        }
        
        @end
        

        【讨论】:

          【解决方案4】:

          (在开始此操作之前,请检查您是否正确地将表格视图单元格出列。这将大大提高性能。)

          用圆角自己绘制图像,并让单元格的背景透明。

          如果您的单元格高度可变,

          1. 使用resizableImageWithCapInsets:(iOS5.0 及更高版本)或早期iOS 已弃用的stretchableImageWithLeftCapWidth:topCapHeight:,以返回将通过重复图像的中心块来扩展的图像。这也将在执行自动调整大小时保护拐角的曲率。或者,

          2. 将您的图像分割成多个片段,并为每个片段设置单独的 UIImageView 实例,并为每个片段设置适当的自动调整大小。就性能而言,这是最佳选择,但您最终可能会拥有多达 9 个网点。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-09-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多