Home>

Differences and relations between uicolor, cgcolor, and cicolor

I recently looked at coregraphics and saw something about cgcolor, so I thought of looking at uicolor and cicolor by the way, to make clear the difference and connection between them.Let's take a look at their three concepts:

I. uicolor

Uicolor is an important class for storing color information in uikit.A uicolor object contains values ​​for color and transparency,Its color space has been optimized for iOS.uicolor contains some class methods for creating some of the most common colors,Such as white, black, red, transparent, etc.These colors also have different color spaces (white and black are kcgcolorspacedevicegray and red is kcgcolorspacedevicergb).

In addition, uicolor has two important attributes:one is cgcolor, and the other is cicolor (added after 5.0). These two properties can link the three objects uicolor, cgcolor, and cicolor.The conversion between these three will be described in detail later.

Cgcolor

Cgcolor is mainly used in the coregaphics framework,cgcolor is actually a structure,And we usually use the reference type cgcolorref when using cgcolor. cgcolor is mainly composed of cgcolorsapce and color components.Same color composition,If the color spaces are different,Parsing results may vary.It's like when we are processing image data,The results of processing rgba format as bgra format can be imagined.In quartz 2d, cgcolor is often used to set the fill color of the context.Set transparency, etc.

1. How to create a cgcolor, the most commonly used function is cgcolorcreate, which has two parameters:

1) colorspace, specify the color space corresponding to cgcolor,Quartz will retain the object, so you can safely release the object after calling it.

2) components, an array of cgfloat, the number of elements in the array is the number of color components n contained in the specified color space, plus the corresponding alpha value.

The function should return a newly created cgcolorref. When we no longer use the object, use the cgcolorrelease function to release the object.

2.Get cgcolor data

Incoming When we create, we pass in two important parameters,When we get cgcolorref, of course, we can get the corresponding colorspace and components.

1) Get colorspace

Through the cgcolorgetcolorspace function, we can get the colorspace corresponding to the current cgcolorref. This function only takes one parameter, which is the cgcolorref of the colorspace i want to obtain. Please see a simple example below:

cgcolorref cgcolor=[uicolor redcolor] .cgcolor;
cgcolorspaceref colorspace=cgcolorgetcolorspace (cgcolor);
nslog (@ "color space:%@", colorspace);

2) Get color components

To get the color value corresponding to cgcolorref,We need to use cgcolorgetnumberofcomponents and cgcolorgetcomponents.Let's first look at the function prototypes of two functions:

size_t cgcolorgetnumberofcomponents (
 cgcolorref color
);
</p>
<p>
const cgfloat * cgcolorgetcomponents (
 cgcolorref color
);

The first function is to get the number of color components contained in cgcolorref,The second function is to get an array of the actual color components,Let's look at a small example:

nsuinteger num=cgcolorgetnumberofcomponents (cgcolor);
const cgfloat * colorcomponents=cgcolorgetcomponents (cgcolor);
for (int i=0;i<num;++ i) {
 nslog (@ "color components%d:%f", i, colorcomponents [i]);
}

Third, cicolor

Cicolor is mainly used for other classes in the core image framework.Such as cifilter, cicontext and ciimage. Today we are mainly concerned with the color value part,The range of color values ​​in cicolor is between 0.0-1.0, 0.0 means that the color component is the minimum,1.0 represents changing the color component to the maximum value.The alpha value is also in the range of 0.0 to 1.0. 0.0 represents full transparency.1.0 means completely opaque,At the same time, the color component of cicolor is usually not multiplied by the alpha value.

We can use the initwithcgcolor:function to create a cicolor from cgcolor. The cgcolorref object passed in can make any color space,However, the core image framework will convert all color spaces to the core image working color space before passing it to the filter kernel.The core image working color space is composed of three color components plus an alpha component (actually kcgcolorspacedevicergb). We will verify this in the following examples.

Fourth, the difference and connection of uicolor, cgcolor, cicolor

1, two attributes of uicolor cgcolor, cicolor

Uicolor's cgcolor is always valid,Regardless of whether it was created by cgcolor, cicolor, or other methods,cgcolor attributes are always valid;But the cicolor attribute is not always valid,Only when uicolor is created by cicolor,He is effective,Otherwise accessing the property will throw an exception,Here is a small example as usual:

//test init uicolor with cgcolor
uicolor * color=[uicolor colorwithcgcolor:[uicolor whitecolor] .cgcolor];
//cgcolor property is always valid
nslog (@ "cgcolor from uicolor%@", color.cgcolor);
</p>
<p>
//don "t use cicolor property
//this property throws an exception if the color object was not initialized with a core image color.
nslog (@ "cicolor from uicolor%@", color.cicolor);//crush

2.Uicolor is initialized using cgcolor

When uicolor is initialized with cgcolor,All the information that cgcolorref contains,Will be kept intact,This includes the color space, and through the small example below, we can also see that if uicolor is initialized using cgcolor, uicolor actually retains a copy of this cgcolorref object directly. Examples are as follows:

//test kcgcolorspacedevicecmyk
cgcolorspaceref cmykspace=cgcolorspacecreatedevicecmyk ();
cgfloat cmykvalue []={1, 1, 0, 0, 1};//blue
cgcolorref colorcmyk=cgcolorcreate (cmykspace, cmykvalue);
cgcolorspacerelease (cmykspace);
nslog (@ "colorcmyk:%@", colorcmyk);
//color with cgcolor, uicolor will just retain it
uicolor * color=[uicolor colorwithcgcolor:colorcmyk];
nslog (@ "cgcolor from uicolor:%@", color.cgcolor);

3.Uicolor is initialized with cicolor

Let's talk about when using cicolor to initialize a uicolor, and then to access the cgcolor attribute of uicolor,We will find that the color space of cgcolor and the color space of cicolor are not exactly the same.In this process cicolor will do a conversion for us.Let ’s take a look at using kcgcolorspacedevicegray, kcgcolorspacedevicergb, and kcgcolorspacedevicecmyk to initialize a cicolor, then use the cicolor to initialize a uicolor, and then visit its cicolor genus, cgcolor properties, view the color space and print color information .

1) Initialize cicolor using kcgcolorspacedevicegray

First look at the code:

//test kcgcolorspacedevicegray
nslog (@ "cgcolor white color:%@", [uicolor whitecolor] .cgcolor);
</p>
<p>
cicolor * cicolor=[cicolor colorwithcgcolor:[uicolor whitecolor] .cgcolor];
nslog (@ "cicolor:%@", cicolor);
nslog (@ "cicolor colorspace:%@", cicolor.colorspace);
color=[uicolor colorwithcicolor:cicolor];
nslog (@ "color%@", color);
//core image converts all color spaces to the core image working color
//space before it passes the color space to the filter kernel.
//kcgcolorspacedevicegray --->kcgcolorspacedevicergb
nslog (@ "cicolor from uicolor:%@", color.cicolor);
nslog (@ "cicolor" s colorspace:%@", color.cicolor.colorspace);
nslog (@ "color" s cgcolor:%@", color.cgcolor);

By running the program,We see thatIf you use a kcgcolorspacedevicegray color space to initialize cicolor, we can see that the color space of cicolor is always kcgcolorspacedevicegray. By accessing the cicolor property of uicolor, we can see that its color space is still kcgcolorspacedevicegray. When the cgcolor attribute,It can be found through printing that the color space has been transformed into kcgcolorspacedevicergb space, and the color values ​​have been correctly converted from the original color space to the new color space.

2) Initialize cicolor using kcgcolorspacedevicergb

Likewise we look at the code:

//test kcgcolorspacedevicergb
nslog (@ "cgcolor red color:%@", [uicolor redcolor] .cgcolor);
cicolor * cicolor=[cicolor colorwithcgcolor:[uicolor redcolor] .cgcolor];
nslog (@ "cicolor:%@", cicolor);
nslog (@ "cicolor colorspace:%@", cicolor.colorspace);
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);

CiThe value of cicolor during the entire process, as well as the values ​​accessed through the cgcolor and cicolor properties of uicolor,Printing out we can find that they are all kcgcolorspacedevicergb space.

4.Use kcgcolorspacedevicecmyk to initialize cicolor

Continue to look at a piece of code:

//test kcgcolorspacedevicecmyk
cgcolorspaceref cmykspace=cgcolorspacecreatedevicecmyk ();
nslog (@ "components number:%zu", cgcolorspacegetnumberofcomponents (cmykspace));
cgfloat cmykvalue []={1, 1, 0, 0, 1};//blue
cgcolorref colorcmyk=cgcolorcreate (cmykspace, cmykvalue);
cgcolorspacerelease (cmykspace);
nslog (@ "colorcmyk:%@", colorcmyk);
cicolor=[cicolor colorwithcgcolor:colorcmyk];
nslog (@ "cicolor:%@", cicolor);//in fact, the color value of cicolor has converted to rgb colorspace
nslog (@ "cicolor colorspace:%@", cicolor.colorspace);
color=[uicolor colorwithcicolor:cicolor];
nslog (@ "uicolor with cicolor:%@", color);
nslog (@ "cicolor from uicolor:%@", color.cicolor);
nslog (@ "cicolor" s colorspace:%@", color.cicolor.colorspace);
//when uicolor init with cicolor, uicolor "s cgcolor will convert other colorspace to kcgcolorspacedevicergb
nslog (@ "cgcolor from uicolor:%@", color.cgcolor);

Throughout the process,We can also find out by running,When we initialize cicolor with a cgcolor in cmyk color space, the color space of cicolor is still cmyk, but the color value has been converted to the rgb color value.When using this cicolor to create a uicolor, when we print the information through the cicolor and cgcolor properties,We will find that the color space of cicolor is still cmyk, but the information obtained by cgcolor printing shows that it has been converted to rgb space.

Five, uicolor extension, how to determine whether two colors are equal

Mention As mentioned earlier,Whether uicolor is initialized with cicolor, cgcolor or other methods,Its cgcolor property is available.Coregraphics provides a method to determine whether two cgcolors are equal.So we can judge whether two uicolors are equal,Here is a simple example:

//judge two cgcolor is equal
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!");
}

The first part of the example is to determine whether the two white uicolors are equal.Although they are all white,But the color space is different.By running we can find thatPrints "the two cgcolor is not equal!". The second part of the example simply creates two uicolors in rgb space. Running the program can see thatThese two colors are the same.

Determine if the color values ​​of two uicolors are equal

A friend asked me two days ago how to determine if the values ​​of two colors are equal.I just want to judge whether the rgba values ​​of the two colors are equal soon.So I started looking for help documentation and found the uicolor class, and it was easy to find the function:

-(bool) getred:(cgfloat *) red green:(cgfloat *) green blue:(cgfloat *) blue alpha:(cgfloat *) alpha;

In this way, you can determine whether the colors of the two uicolor objects are equal.code show as below:

enum {
enequal,ennoteaual,encannotconvert, };
typedef nsinteger kcompareresult;
</p>
<p>
+ (kcompareresult) isthesamecolor:(uicolor *) color
redvalue:(cgfloat) rvalue
greenvalue:(cgfloat) gvalue bluevalue:(cgfloat) bvalue
alphavalue:(cgfloat) avalue
{
</p>
<p>
if ([color respondstoselector:@selector (getred:green:blue:alpha :)]) {
</p>
<p>
cgfloat redvalue, greenvalue, bluevalue, alphavalue;
if ([color getred:&redvalue green:&greenvalue blue:&bluevalue alpha:&alphavalue]) {
if (redvalue == rvalue &&greenvalue == gvalue &&bluevalue == bvalue &&alphavalue == avalue) {
return enequal;
}
else {
return ennoteaual;
}
}
else {//can not convert
return encannotconvert;
}
}
}
ios
  • Previous How the GridView control displays the sequence number
  • Next Javascript control div attribute dynamic change instance analysis