【iOS】UIColor、CGColor、CIColor的区别和联系

2024-01-15 04:52

本文主要是介绍【iOS】UIColor、CGColor、CIColor的区别和联系,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

编者在实验室小组的指导下,仿写了许多App,其中UI的颜色模仿也是令人头痛的点。设计颜色一般使用UIColor类方法直接获取颜色:

请添加图片描述

有时会使用

+ (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;
+ (UIColor *)colorWithHue:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness alpha:(CGFloat)alpha;

这两个方法,通过取色器获取指定颜色的RGB参数或HSB参数。

也会留意到以下这两个方法,本文就此来展开学习:

+(UIColor *)colorWithCGColor:(CGColorRef)cgColor;#if __has_include(<CoreImage/CoreImage.h>)
+(UIColor *)colorWithCIColor:(CIColor *)ciColor API_AVAILABLE(ios(5.0));
#endif

目录

    • 介绍
      • UIColor
      • CGColor
      • CIColor
    • UIColor、CGColor、CIColor的区别与联系
      • UIColor的两个属性CGColor、CIColor
      • 使用CGColor初始化UIColor
      • 使用CIColor初始化UIColor
    • UIColor拓展:判断两个颜色是否相等


了解CGColorCIColor前,这里先拓展一个关于颜色的常识,关于颜色空间分类:

  • RGB:R代表红色,G代表绿色,B代表蓝色。通过调整红、绿、蓝的亮度和混合来创建各种颜色,因为三种颜色都有256个亮度水平级,所以三种色彩叠加就形成1670万种颜色了,也就是真彩色,通过它们足以在现绚丽的世界。
  • HSB:H代表色相、S代表饱和度、B代表亮度。基于人类感知,以人眼为理论。色相表示色彩的基本属性,用一个角度值(0~360度)来表示。饱和度表示颜色的鲜艳程度(0~100%)。亮度表示颜色的明暗程度(0~100%)。
  • LAB:L代表亮度,A和B代表色彩。亮度(0~100%)表示由黑到白的程度。A是从深绿色(底亮度)到灰色(中亮度值)再到亮粉红色(高亮度值)。B表示从亮蓝色到灰色再到黄色。可用于描述非线性的颜色变化,广泛应用于色彩匹配和颜色差异度量。
  • CMYK:代表印刷打印上的颜色,C(Cyan)代表青色,M(Magenta)代表洋红色,Y(Yellow)代表黄色,K(Key)代表黑色。在实际应用中,青色、洋红色和黄色很难叠加形成真正的黑色,最深才不过是褐色,因此引入K——黑色,作用是强化暗调,加深暗部色彩。

介绍

UIColor

UIColor是UIKit中用于表示颜色的类,一个UIColor对象包含了颜色和透明度的值,可以用来表示不同颜色空间(RGB、HSB)的颜色。

UIColor提供了各种便捷的方法创建和管理颜色,正如上面提到的,可以使用与定义的颜色常量,也可以使用RGB或HSB的值来自定义颜色。UIColor还提供了方法来操纵混合、调整透明度等。

CGColor

CGColor是Core Graphics框架(Apple的绘图框架)中用于表示颜色的数据类型,本质是一个结构体,是一种低级的颜色表示方式,更接近图形底层,提供了底层的图形渲染和绘制功能。

请添加图片描述

CGColor实际上是指向CGColorRef的指针,主要由CGColorSpace(颜色空间)ColorComponents(颜色组成信息)。同样的颜色组成,如果颜色空间不同,解析出来的结果可能会有所不同。

来看一下如何获取CGColor的数据,当然,获取到了CGColorRef后就可以拿到对应的ColorSpace以及Components:

  1. 获取ColorSpace

只需将相应的CGColorRef对象传入CGColorGetColorSpace()函数中

CGColorRef cgColor = [UIColor redColor].CGColor;
CGColorSpaceRef colorSpace = CGColorGetColorSpace(cgColor);
NSLog(@"color space:%@", colorSpace);

请添加图片描述

可以看到是RGB类型。

  1. 获取ColorComponents

先来看看需要用到的两个函数的原型:

请添加图片描述

可以看到前者返回的是CGColorRef的中包含的颜色组成部分的个数(unsigned long类型)。
后者返回实际的颜色组成部分的数组(CGFloat *浮点类型数组),该数组的个数就是指定色彩空间包含的颜色分量数以及对应的alpha值(透明度)。

//获得颜色组成部分的个数
NSUInteger numOfComponents = CGColorGetNumberOfComponents(cgColor);//获取实际颜色的组成部分的数组
const CGFloat* colorComponents = CGColorGetComponents(cgColor);for (int i = 0; i < numOfComponents; i++) {NSLog(@"color components %d : %f", i, colorComponents[i]);
}

请添加图片描述

既然是颜色空间是RGB类型,那数组的每个值依次对应的是R、G、B、Alpha的值。

CIColor

CIColor是Core Image框架中用于表示颜色的类,与UIColor有些许相似,但更偏向专门于处理Core Image滤镜中的颜色操作。

CIColor可表示多个颜色空间,包括RGB、HSB、LAB等,它的属性包括颜色分量值(比如R、G、B或H、S、B的值)、透明度等,还提供了一系列方法来创建和操作颜色,如颜色混合、色彩调整等。

CIColor的使用见后面的示例。

UIColor、CGColor、CIColor的区别与联系

UIColor的两个属性CGColor、CIColor

不管是通过CGColorCIColor还是其他方法创建的UIColor,CGColor属性总是有效的,但CIColor属性就不总是有效。只有UIColor是通过CIColor创建时,CIColor才有效,否则访问该属性将会出现异常。

现通过CGColor初始化UIColor来验证一下:

UIColor* color = [UIColor colorWithCGColor: [UIColor whiteColor].CGColor];
NSLog(@"CGColor from UIColor: %@", color.CGColor);
//NSLog(@"CIColor from UIColor: %@", color.CIColor);

请添加图片描述
正常运行。

如果访问CIColor:

UIColor* color = [UIColor colorWithCGColor: [UIColor whiteColor].CGColor];
//NSLog(@"CGColor from UIColor: %@", color.CGColor);
NSLog(@"CIColor from UIColor: %@", color.CIColor);

请添加图片描述

crush,程序崩溃。

使用CGColor初始化UIColor

当使用CGColor初始化UIColor时,所有CGColorRef包含的信息,都会被原封不动地保留(retain),其中就包括Colorspace。

//这里颜色空间使用CMYK
CGColorSpaceRef cmykSpace = CGColorSpaceCreateDeviceCMYK();CGFloat cmykComponents[] = {1, 1, 0, 0, 1};  //蓝色
CGColorRef colorCMYK = CGColorCreate(cmykSpace, cmykComponents);
CGColorSpaceRelease(cmykSpace);
NSLog(@"colorCMYK:%@", colorCMYK);//使用CGColor初始化UIColor
UIColor* color = [UIColor colorWithCGColor: colorCMYK];
NSLog(@"CGColor from UIColor:%@", color.CGColor);

请添加图片描述

使用CIColor初始化UIColor

当使用CIColor初始化UIColor后,再去访问UIColor的CGColor属性时,会发现CGColor的颜色空间和设置的CIColor的颜色空间不完全一样,这里CIColor已经做了一个转换。下面我们使用Gray(灰度)、RGB、CMYK三种颜色空间来设置CIColor,并初始化UIColor,再去访问其CIColor、CGColor属性,查看颜色空间和颜色信息。

  1. kCGColorSpaceDeviceGraykCGColorSpaceDeviceRGB
    //白色的颜色空间就是Gray
//    NSLog(@"CGColor white color:%@", [UIColor whiteColor].CGColor);//红色的颜色空间时RGBNSLog(@"CGColor red color:%@", [UIColor redColor].CGColor);putchar('\n');//设置CIColorCIColor* ciColor = [CIColor colorWithCGColor: [UIColor redColor].CGColor];NSLog(@"ciColor:%@", ciColor);NSLog(@"ciColor colorSpace:%@", ciColor.colorSpace);putchar('\n');//初始化UIColor* color = [UIColor colorWithCIColor: ciColor];NSLog(@"color:%@", color);NSLog(@"ciColor from UIColor:%@", color.CIColor);NSLog(@"ciColor's colorSpace:%@", color.CIColor.colorSpace);NSLog(@"color's CGColor:%@", color.CGColor);

请添加图片描述

可以看到,使用颜色空间为RGB或Gray的CGColor设置CIColor时,CIColor的颜色空间保持不变,通过UIColor访问CIColor和CGColor属性时,颜色空间也保持不变。

  1. kCGColorSpaceDeviceCMYK
CGColorSpaceRef cmykSpace = CGColorSpaceCreateDeviceCMYK();
NSLog(@"Components number: %lu", CGColorSpaceGetNumberOfComponents(cmykSpace));putchar('\n');CGFloat cmykComponents[] = {1, 1, 0, 0, 1};  //蓝色
CGColorRef colorCMYK = CGColorCreate(cmykSpace, cmykComponents);
CGColorSpaceRelease(cmykSpace);
NSLog(@"colorCMYK:%@", colorCMYK);putchar('\n');CIColor* ciColor = [CIColor colorWithCGColor: colorCMYK];
NSLog(@"ciColor: %@", ciColor);
NSLog(@"ciColor colorSpace: %@", ciColor.colorSpace);putchar('\n');UIColor* color = [UIColor colorWithCIColor: ciColor];
NSLog(@"color: %@", color);
NSLog(@"ciColor from UIColor: %@", color.CIColor);
NSLog(@"ciColor's colorSpace: %@", color.CIColor.colorSpace);
NSLog(@"cgColor from UIColor: %@", color.CGColor);

在这里插入图片描述

可以看出,使用颜色空间为CMYK的CGColor设置CIColor时,CIColor颜色空间不变,但颜色值已经转换成RGB的颜色值。通过UIColor访问CGColor和CIColor属性时,同样地,颜色空间不变,颜色值改变。

UIColor拓展:判断两个颜色是否相等

前面提到一点,不管UIColor使用CIColor,CGColor还是其他方式初始化的,其CGColor属性都是可用的。 CoreGraphics中提供一个方法可以判断两个CGColor是否相等,因此我们可以通过判断两个UIColor是否相等:

if (CGColorEqualToColor([UIColor whiteColor].CGColor, [UIColor colorWithRed: 1.0 green: 1.0 blue: 1.0 alpha: 1.0].CGColor)) {NSLog(@"两颜色相等");
} else {NSLog(@"两颜色不相等");
}
if (CGColorEqualToColor([UIColor colorWithRed: 1.0 green: 1.0 blue: 1.0 alpha: 1.0].CGColor, [UIColor colorWithRed: 1.0 green: 1.0 blue: 1.0 alpha: 1.0].CGColor)) {NSLog(@"两颜色相等");
} else {NSLog(@"两颜色不相等");
}

请添加图片描述

结果如图,前者虽然都是白色,但颜色空间不一样。

这篇关于【iOS】UIColor、CGColor、CIColor的区别和联系的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/607719

相关文章

JAVA覆盖和重写的区别及说明

《JAVA覆盖和重写的区别及说明》非静态方法的覆盖即重写,具有多态性;静态方法无法被覆盖,但可被重写(仅通过类名调用),二者区别在于绑定时机与引用类型关联性... 目录Java覆盖和重写的区别经常听到两种话认真读完上面两份代码JAVA覆盖和重写的区别经常听到两种话1.覆盖=重写。2.静态方法可andro

C++中全局变量和局部变量的区别

《C++中全局变量和局部变量的区别》本文主要介绍了C++中全局变量和局部变量的区别,全局变量和局部变量在作用域和生命周期上有显著的区别,下面就来介绍一下,感兴趣的可以了解一下... 目录一、全局变量定义生命周期存储位置代码示例输出二、局部变量定义生命周期存储位置代码示例输出三、全局变量和局部变量的区别作用域

MyBatis中$与#的区别解析

《MyBatis中$与#的区别解析》文章浏览阅读314次,点赞4次,收藏6次。MyBatis使用#{}作为参数占位符时,会创建预处理语句(PreparedStatement),并将参数值作为预处理语句... 目录一、介绍二、sql注入风险实例一、介绍#(井号):MyBATis使用#{}作为参数占位符时,会

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

Javaee多线程之进程和线程之间的区别和联系(最新整理)

《Javaee多线程之进程和线程之间的区别和联系(最新整理)》进程是资源分配单位,线程是调度执行单位,共享资源更高效,创建线程五种方式:继承Thread、Runnable接口、匿名类、lambda,r... 目录进程和线程进程线程进程和线程的区别创建线程的五种写法继承Thread,重写run实现Runnab

C++中NULL与nullptr的区别小结

《C++中NULL与nullptr的区别小结》本文介绍了C++编程中NULL与nullptr的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编... 目录C++98空值——NULLC++11空值——nullptr区别对比示例 C++98空值——NUL

Conda与Python venv虚拟环境的区别与使用方法详解

《Conda与Pythonvenv虚拟环境的区别与使用方法详解》随着Python社区的成长,虚拟环境的概念和技术也在不断发展,:本文主要介绍Conda与Pythonvenv虚拟环境的区别与使用... 目录前言一、Conda 与 python venv 的核心区别1. Conda 的特点2. Python v

Go语言中make和new的区别及说明

《Go语言中make和new的区别及说明》:本文主要介绍Go语言中make和new的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1 概述2 new 函数2.1 功能2.2 语法2.3 初始化案例3 make 函数3.1 功能3.2 语法3.3 初始化

深度解析Java项目中包和包之间的联系

《深度解析Java项目中包和包之间的联系》文章浏览阅读850次,点赞13次,收藏8次。本文详细介绍了Java分层架构中的几个关键包:DTO、Controller、Service和Mapper。_jav... 目录前言一、各大包1.DTO1.1、DTO的核心用途1.2. DTO与实体类(Entity)的区别1

深度解析Spring Boot拦截器Interceptor与过滤器Filter的区别与实战指南

《深度解析SpringBoot拦截器Interceptor与过滤器Filter的区别与实战指南》本文深度解析SpringBoot中拦截器与过滤器的区别,涵盖执行顺序、依赖关系、异常处理等核心差异,并... 目录Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现