iOS沉思录UIImage圆角矩形的‘离屏渲染’和‘在屏渲染’实现方法
Posted Mr_厚厚
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS沉思录UIImage圆角矩形的‘离屏渲染’和‘在屏渲染’实现方法相关的知识,希望对你有一定的参考价值。
按照背后的渲染方式,实现UIView及其子类的圆角效果有两种方法:一种是直接设置layer的圆角属性,为‘离屏渲染’;另一种是自定义圆角绘制方法,实现‘当前屏幕渲染’。
离屏渲染和当前屏幕渲染
当前屏幕渲染(On-Screen Rendering): 指的是GPU直接在当前显示的屏幕缓冲区中进行图形渲染,不需要提前另开缓冲区也就不需要缓冲区的切换,因此性能较高;
离屏渲染(Off-Screen Rendering): 简单说就是提前另开一个缓冲区进行图形渲染,由于显示需要和当前屏幕缓冲区进行切换,所以很耗费性能。通常圆角、遮罩、不透明度、阴影、渐变、光栅化和抗锯齿等设置都会触发离屏渲染。
‘离屏渲染’实现圆角:
ios中圆角效果实现的最简单、最直接的方式,是直接修改View的layer层参数,会触发‘离屏渲染’,性能不高:
/* 设置圆角半径 */
view.layer.cornerRadius = 5;
/* 将边界以外的区域遮盖住 */
view.layer.masksToBounds = YES;
‘当前屏幕渲染’实现圆角:
另外一种则是实现on-screen-rendering,直接在当前屏幕渲染绘制,提高性能。
为UIImage类扩展一个实例函数:
/**
* On-screen-renderring绘制UIImage矩形圆角
*/
- (UIImage *)imageWithCornerRadius:(CGFloat)radius ofSize:(CGSize)size{
/* 当前UIImage的可见绘制区域 */
CGRect rect = (CGRect){0.f,0.f,size};
/* 创建基于位图的上下文 */
UIGraphicsBeginImageContextWithOptions(size, NO, UIScreen.mainScreen.scale);
/* 在当前位图上下文添加圆角绘制路径 */
CGContextAddPath(UIGraphicsGetCurrentContext(), [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius].CGPath);
/* 当前绘制路径和原绘制路径相交得到最终裁剪绘制路径 */
CGContextClip(UIGraphicsGetCurrentContext());
/* 绘制 */
[self drawInRect:rect];
/* 取得裁剪后的image */
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
/* 关闭当前位图上下文 */
UIGraphicsEndImageContext();
return image;
}
使用时,让实例化的UIImage对象调用一下上面的实例方法即可:
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 100, 100)];
/* 创建并初始化UIImage */
UIImage *image = [UIImage imageNamed:@"icon"];
/* 添加圆角矩形 */
image = [image imageWithCornerRadius:50 ofSize:imageView.frame.size];
[imageView setImage:image];
完整代码
UIImage类别扩展在屏渲染实例函数:
//
// UIImage+RadiusCorner.h
// SingleView
//
// Created by Xinhou Jiang on 19/4/17.
// Copyright © 2017年 Xinhou Jiang. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIImage (RadiusCorner)
/* On-screen-renderring绘制UIImage矩形圆角 */
- (UIImage *)imageWithCornerRadius:(CGFloat)radius ofSize:(CGSize)size;
@end
//
// UIImage+RadiusCorner.m
// SingleView
//
// Created by Xinhou Jiang on 19/4/17.
// Copyright © 2017年 Xinhou Jiang. All rights reserved.
//
#import "UIImage+RadiusCorner.h"
@implementation UIImage (RadiusCorner)
/**
* On-screen-renderring绘制UIImage矩形圆角
*/
- (UIImage *)imageWithCornerRadius:(CGFloat)radius ofSize:(CGSize)size{
/* 当前UIImage的可见绘制区域 */
CGRect rect = (CGRect){0.f,0.f,size};
/* 创建基于位图的上下文 */
UIGraphicsBeginImageContextWithOptions(size, NO, UIScreen.mainScreen.scale);
/* 在当前位图上下文添加圆角绘制路径 */
CGContextAddPath(UIGraphicsGetCurrentContext(), [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius].CGPath);
/* 当前绘制路径和原绘制路径相交得到最终裁剪绘制路径 */
CGContextClip(UIGraphicsGetCurrentContext());
/* 绘制 */
[self drawInRect:rect];
/* 取得裁剪后的image */
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
/* 关闭当前位图上下文 */
UIGraphicsEndImageContext();
return image;
}
@end
测试代码:
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(50, 50, 100, 100)];
UIImage *image = [UIImage imageNamed:@"icon"];
/* 1. on-screen-renderring */
//image = [image imageWithCornerRadius:50 ofSize:imageView.frame.size];
[imageView setImage:image];
/* 2. off-screen-renderring */
imageView.layer.cornerRadius = 20;
imageView.layer.masksToBounds = YES;
[self.view addSubview:imageView];
}
@end
以上是关于iOS沉思录UIImage圆角矩形的‘离屏渲染’和‘在屏渲染’实现方法的主要内容,如果未能解决你的问题,请参考以下文章