前言
UIColor是UIKit中存储颜色信息的一个重要类。一个UIColor对象包含了颜色和透明度的值,它的颜色空间已经针对iOS进行了优化。UIColor提供了一些常用的创建颜色的方法,如白色、黑色、红色等。这些颜色的色彩空间也有所不同,例如白色和黑色是kCGColorSpaceDeviceGray,红色的色彩空间是kCGColorSpaceDeviceRGB。此外,UIColor还有两个重要的属性:一个是CGColor,另一个是CIColor(自5.0版本起添加)。这两个属性可以将UIColor、CGColor和CIColor这三个对象联系起来。本篇文章将着重介绍UIColor。
一、创建颜色的方法
1. 使用white和alpha参数创建颜色:
```objective-c
// white的范围是0~1,代表黑~白,中间过度灰色;alpha是透明度,范围为0~1,0表示完全透明,1表示不透明
```
2. 使用hue、saturation、brightness和alpha参数创建颜色:
```objective-c
// hue表示色调;saturation表示饱和度;brightness表示亮度;alpha表示透明度
UIColor *color = [UIColor colorWithHue:0.5 saturation:0.8 brightness:0.6 alpha:0.7];
```
3. 使用red、green、blue和alpha参数创建颜色:
```objective-c
// red表示红;green表示绿;blue表示蓝;alpha表示透明度
CGFloat redValue = 1;
CGFloat greenValue = 0;
CGFloat blueValue = 0;
UIColor *color = [UIColor colorWithRed:redValue green:greenValue blue:blueValue alpha:0.8];
```
4. 使用CMYK空间创建颜色并转换为UIColor:
```objective-c
CGColorSpaceRef cmykSpace = CGColorSpaceCreateDeviceCMYK();
CGFloat cmykValues[] = {1, 1, 0, 0, 1}; // Cyan Magenta Yellow Key (blue)
CGColorRef colorCMYK = CGColorCreate(cmykSpace, cmykValues);
CGColorSpaceRelease(cmykSpace);
NSLog(@"colorCMYK: %@", colorCMYK);
// color with CGColor, uicolor will just retain it
UIColor *color = [UIColor colorWithCGColor:colorCMYK];
NSLog(@"CGColor from UIColor: %@", color.CGColor);
```
以上就是关于UIColor的一些基本用法和方法。
你可以使用`kCGColorSpaceDeviceGray`来初始化CIColor,然后使用`CGImageGetColorspace()`方法获取图片的颜色空间,最后将CIImage转换为CGImage并获取其颜色。如果你想从一张图片中获取颜色,你可以使用以下代码:
```swift
let image = UIImage(named: "your_image_name")
let color = image?.cgImage?.colorSpace?.createDeviceGrayColor((image?.cgImage)!)
print(color)
```
以下是重构后的代码:
```objc
NSLog(@"CGColor white color:%@", [UIColor whiteColor].CGColor); // CGColor white color:
// 创建CIColor
CIColor *ciColor = [CIColor colorWithCGColor:[UIColor whiteColor].CGColor];
NSLog(@"cicolor: %@", ciColor); // cicolor: (1 1 1 1)
NSLog(@"cicolor colorspace: %@", ciColor.colorSpace); // cicolor colorspace:
// 创建UIColor
UIColor *uicolor = [UIColor colorWithCIColor:ciColor];
NSLog(@"uicolor:%@", uicolor); // color CIColor 1 1 1 1
// Core Image 在将颜色空间传递给滤波器内核之前,会将所有颜色空间转换为 Core Image 工作颜色空间。
// kCGColorSpaceDeviceGray ----> kCGColorSpaceDeviceRGB
NSLog(@"cicolor from UIColor: %@", uicolor.CIColor); // cicolor from UIColor: (1 1 1 1)
NSLog(@"cicolor's colorspace: %@", uicolor.CIColor.colorSpace); // cicolor's colorspace:
NSLog(@"uicolor CGColor: %@", uicolor.CGColor); // color's CGColor:
总结:
通过运行程序,我们发现,当使用kCGColorSpaceDeviceGray颜色空间的CGColor初始化CIColor时,CIColor的色彩空间始终为kCGColorSpaceDeviceGray。然而,当我们访问UIColor的CGColor属性并打印时,可以发现其色彩空间已经转换为kCGColorSpaceDeviceRGB,并且颜色值也从原始颜色空间正确地转换到了新的颜色空间。
(2) 使用kCGColorSpaceDeviceRGB初始化CIColor
在第二个示例中,我们尝试使用kCGColorSpaceDeviceRGB颜色空间的CGColor来初始化CIColor。运行程序后,我们发现CIColor的色彩空间已经成功转换为kCGColorSpaceDeviceRGB,颜色值也正确地从原始颜色空间转换到了新的颜色空间。这表明,通过正确的颜色空间初始化,我们可以确保CIColor的色彩空间和颜色值与实际图像一致。
```objc
// 打印红色颜色的 CGColor
NSLog(@"CGColor red color: %@", [UIColor redColor].CGColor); // CGColor red color:
// 将 CGColor 转换为 CIColor
CIColor *ciColor = [CIColor colorWithCGColor:[UIColor redColor].CGColor];
NSLog(@"cicolor: %@", ciColor); // cicolor: (1 0 0 1)
// 打印 CIColor 的颜色空间
NSLog(@"cicolor colorspace: %@", ciColor.colorSpace); // cicolor colorspace:
// 将 CIColor 转换为 UIColor
UIColor *uicolor = [UIColor colorWithCIColor:ciColor];
NSLog(@"uicolor %@", uicolor); // color CIColor (1 0 0 1)
// 从 UIColor 中获取 CIColor
NSLog(@"cicolor from UIColor: %@", uicolor.CIColor); // cicolor from UIColor: (1 0 0 1)
// 打印 CIColor 在从 uicolor 中的 colorSpace
NSLog(@"cicolor's colorspace: %@", uicolor.CIColor.colorSpace); // cicolor's colorspace:
// 从 uicolor 中获取 CGColor
NSLog(@"uicolor CGColor: %@", uicolor.CGColor); // uicolor's CGColor:
```
总结:
在本文中,我们通过CIColor、UIColor的CGColor和CIColor属性访问到的值进行了分析。结果显示,这些值都属于kCGColorSpaceDeviceRGB空间。此外,我们还探讨了如何使用kCGColorSpaceDeviceCMYK初始化CIColor。
以下是重构后的代码:
```objective-c
// 创建设备CMYK颜色空间
CGColorSpaceRef cmykSpace = CGColorSpaceCreateDeviceCMYK();
NSLog(@"Components number: %zu", CGColorSpaceGetNumberOfComponents(cmykSpace)); // Components number: 4
// 设置CMYK值
CGFloat cmykValue[] = {1, 1, 0, 0, 1};
// 创建CMYK颜色
CGColorRef colorCMYK = CGColorCreate(cmykSpace, cmykValue);
CGColorSpaceRelease(cmykSpace);
NSLog(@"colorCMYK: %@", colorCMYK); // colorCMYK:
// 将CMYK颜色转换为CIColor
CIColor* ciColor = [CIColor colorWithCGColor:colorCMYK];
NSLog(@"cicolor: %@", ciColor); // cicolor: (0 0 1 1)
// 注意:实际上,CIColor的颜色值已经转换为RGB颜色空间
NSLog(@"cicolor colorspace: %@", ciColor.colorSpace); // cicolor colorspace:
// 将CIColor转换为UIColor
UIColor* uicolor = [UIColor colorWithCIColor:ciColor];
NSLog(@"UIColor with CIColor: %@", uicolor); // UIColor with CIColor: CIColor 0 0 1 1
NSLog(@"cicolor from UIColor: %@", uicolor.CIColor); // cicolor from UIColor: (0 0 1 1)
NSLog(@"cicolor's colorspace: %@", uicolor.CIColor.colorSpace); // cicolor's colorspace:
NSLog(@"cgcolor from UIColor: %@", uicolor.CGColor); // cgcolor from UIColor:
```
在颜色处理过程中,我们发现了一个有趣的现象:当我们使用CMYK颜色空间的CGColor初始化CIColor时,CIColor的颜色空间仍然是CMYK,但颜色值已转换为RGB值。而当我们使用该CIColor创建一个UIColor并通过CGColor属性打印信息时,我们会发现CIColor的色彩空间仍然是CMYK,但CGColor打印所得到的信息说明它已经被转换成RGB空间了。
以下是关于颜色初始化的方法总结:
1. 使用白色和透明度参数:`- (UIColor *)initWithWhite:(CGFloat)white alpha:(CGFloat)alpha;`
2. 使用色调、饱和度、亮度和透明度参数:`- (UIColor *)initWithHue:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness alpha:(CGFloat)alpha;`
3. 使用红、绿、蓝和透明度参数:`- (UIColor *)initWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;`
4. 使用CGColor初始化:`- (UIColor *)initWithCGColor:(CGColorRef)cgColor;`
5. 使用UIImage初始化:`- (UIColor *)initWithPatternImage:(UIImage *)image;`
6. 使用CIColor初始化(仅适用于iOS 5.0及以上版本):`- (UIColor *)initWithCIColor:(CIColor)ciColor NS_AVAILABLE_IOS(5_0);`
此外,还有一些方便创建颜色的方法,这些颜色会尽可能精确地校准,并且已经缓存。例如:
1. 黑色:`+ (UIColor *)blackColor; // 0.0 white`
2. 深灰色:`+ (UIColor *)darkGrayColor; // 0.333 white`
3. 浅灰色:`+ (UIColor *)lightGrayColor; // 0.667 white`
```objc
// 定义颜色常量
#define kColorWhite (UIColor *)[UIColor whiteColor] // 1.0 white
#define kColorGray [UIColor grayColor] // 0.5 white
#define kColorRed [UIColor redColor] // 1.0, 0.0, 0.0 RGB
#define kColorGreen [UIColor greenColor] // 0.0, 1.0, 0.0 RGB
#define kColorBlue [UIColor blueColor] // 0.0, 0.0, 1.0 RGB
#define kColorCyan [UIColor cyanColor] // 0.0, 1.0, 1.0 RGB
#define kColorYellow [UIColor yellowColor] // 1.0, 1.0, 0.0 RGB
#define kColorMagenta [UIColor magentaColor] // 1.0, 0.0, 1.0 RGB
#define kColorOrange [UIColor orangeColor] // 1.0, 0.5, 0.0 RGB
#define kColorPurple [UIColor purpleColor] // 0.5, 0.0, 0.5 RGB
#define kColorBrown [UIColor brownColor] // 0.6, 0.4, 0.2 RGB
#define kColorClear [UIColor clearColor] // 0.0 white, 0.0 alpha
// 其他操作
- (UIColor *)getColorWithAlpha:(CGFloat)alpha;
// 设置颜色:在当前绘制上下文中设置填充和线段颜色;
- (void)setFillAndLineColor:(UIColor *)color;
// 设置填充
- (void)setStrokeWidth:(CGFloat)width;
// 设置线段
- (void)setStrokeColor:(UIColor *)color;
```
```objc
#import
@interface MyView : UIView
- (void)drawRect:(CGRect)rect;
- (BOOL)isColorEqual:(UIColor *)color1 color2:(UIColor *)color2;
@end
@implementation MyView
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
UIColor *redColor = [UIColor redColor];
UIColor *purpleColor = [UIColor purpleColor];
// 判断两个颜色是否相等
BOOL isEqual = [self isColorEqual:redColor color2:purpleColor];
NSLog(@"两个颜色是否相等: %@", isEqual ? @"相等" : @"不相等");
//1.获得图形上下文
CGContextRef context = UIGraphicsGetCurrentContext();
//2.绘制路径(相当于前面创建路径并添加路径到图形上下文两步操作)
CGContextMoveToPoint(context, 20, 50);
CGContextAddLineToPoint(context, 20, 100);
CGContextAddLineToPoint(context, 300, 100);
//封闭路径:a.创建一条起点和终点的线,不推荐
//CGPathAddLineToPoint(path, nil, 20, 50);
//封闭路径:b.直接调用路径封闭方法
CGContextClosePath(context);
//4.绘制路径
CGContextDrawPath(context, kCGPathFillStroke);
}
- (BOOL)isColorEqual:(UIColor *)color1 color2:(UIColor *)color2 {
// 通过判断两个UIColor是否相等来判断CGColor是否相等
BOOL isEqual = [[color1 CGColor] == [[color2 CGColor]]];
return isEqual;
}
@end
```
```objc
if (CGColorEqualToColor([UIColor whiteColor].CGColor, [UIColor colorWithRed:1 green:1 blue:1 alpha:1].CGColor)) {
NSLog(@"The two CGColor is equal!");
} else {
NSLog(@"The two CGColor is not equal!");
}
if (CGColorEqualToColor([UIColor colorWithRed:1 green:1 blue:1 alpha:1].CGColor, [UIColor colorWithRed:1 green:1 blue:1 alpha:1].CGColor)) {
NSLog(@"The two CGColor is equal!");
} else {
NSLog(@"The two CGColor is not equal!");
}
```
例子中第一部分是判断两个白色的UIColor是否相等,虽然都是白色,但是颜色控件是不一样的,通过运行我们可以发现,打印出『 The two CGColor is not equal!』。例子的第二部分简单的创建两个RGB空间的UIColor,运行程序可以看出,这两个颜色是相同的。
以下是将提供的内容重构并保持段落结构后的代码:
CGColor from UIColor <CGColor 0x7f8411f61ac0> [<CGColorSpace 0x7f8411e63990> (kCGColorSpaceDeviceGray)] ( 1 1 )
#if __has_include(<CoreImage/CoreImage.h>) @property(nonatomic,readonly) CIColor *CIColor NS_AVAILABLE_IOS(5_0); #endif
UIColor *color = [UIColor whiteColor]; //未使用CIColor初始化的颜色,使用如下方法获取CIColor会产生崩溃 NSLog(@"CIColor from UIColor %@", color.CIColor); // crush
// CGColor from UIColor
// #if __has_include(<CoreImage/CoreImage.h>) @property(nonatomic,readonly) CIColor *CIColor NS_AVAILABLE_IOS(5_0); #endif
// UIColor *color = [UIColor whiteColor]; //未使用CIColor初始化的颜色,使用如下方法获取CIColor会产生崩溃 NSLog(@"CIColor from UIColor %@", color.CIColor); // crush
// 将提供的内容重构为一个函数,以避免崩溃的问题
- (CIColor *)getCIColorFromUIKitColor:(UIColor *)uiKitColor {
return [uiKitColor getCIColor];
}
// 在需要的地方调用该函数来获取CIColor
CIColor *ciColor = [self getCIColorFromUIKitColor:color];