[英]How do I convert a UIColor to a 3/4/6/8 digits hexadecimal string in Swift?
How do I convert a UIColor to a hexadecimal string of 3/4/6/8 digits in Swift? 如何在Swift中将UIColor转换为3/4/6/8位数的十六进制字符串?
How do I get a spectific one? 我如何获得一个特定的? for example, get "#0000FFFF" by calling
UIColor.blue.eightDigitsString
例如,通过调用
UIColor.blue.eightDigitsString
获得“#0000FFFF”
5.2.
5.2。 The RGB hexadecimal notations: #RRGGBB
RGB十六进制表示法:#RRGGBB
The CSS hex color notation allows a color to be specified by giving the channels as hexadecimal numbers, which is similar to how colors are often written directly in computer code.
CSS十六进制颜色表示法通过将通道指定为十六进制数字来指定颜色,这类似于通常直接在计算机代码中编写颜色的方式。 It's also shorter than writing the same color out in rgb() notation.
它比用rgb()表示法写相同的颜色还短。
The syntax of a is a <hash-token> token whose value consists of 3, 4, 6, or 8 hexadecimal digits.
a的语法是<hash-token>令牌,其值由3、4、6或8个十六进制数字组成。 In other words, a hex color is written as a hash character, "#", followed by some number of digits 0-9 or letters af (the case of the letters doesn't matter - #00ff00 is identical to #00FF00).
换句话说,十六进制颜色被写为哈希字符“#”,后跟一些数字0-9或字母af(字母大小写无关紧要-#00ff00与#00FF00相同)。
The number of hex digits given determines how to decode the hex notation into an RGB color:
给定的十六进制数字的数量决定了如何将十六进制表示法解码为RGB颜色:
6 digits
6位数
The first pair of digits, interpreted as a hexadecimal number, specifies the red channel of the color, where 00 represents the minimum value and ff (255 in decimal) represents the maximum.第一对数字(解释为十六进制数字)指定颜色的红色通道,其中00表示最小值,ff(十进制255)表示最大值。 The next pair of digits, interpreted in the same way, specifies the green channel, and the last pair specifies the blue.
以相同方式解释的下一对数字指定绿色通道,最后一对数字指定蓝色通道。 The alpha channel of the color is fully opaque.
颜色的Alpha通道是完全不透明的。 In other words, #00ff00 represents the same color as rgb(0 255 0) (a lime green).
换句话说,#00ff00表示与rgb(0 255 0)相同的颜色(柠檬绿)。
8 digits
8位数字
The first 6 digits are interpreted identically to the 6-digit notation.前6位数字与6位数字符号的解释相同。 The last pair of digits, interpreted as a hexadecimal number, specifies the alpha channel of the color, where 00 represents a fully transparent color and ff represent a fully opaque color.
最后一对数字(解释为十六进制数字)指定颜色的Alpha通道,其中00表示完全透明的颜色,ff表示完全不透明的颜色。 In other words, #0000ffcc represents the same color as rgb(0 0 100% / 80%) (a slightly-transparent blue).
换句话说,#0000ffcc表示与rgb(0 0 100%/ 80%)(略透明的蓝色)相同的颜色。
3 digits
3位数
This is a shorter variant of the 6-digit notation.这是6位数符号的缩写。 The first digit, interpreted as a hexadecimal number, specifies the red channel of the color, where 0 represents the minimum value and f represents the maximum.
第一位解释为十六进制数字,指定该颜色的红色通道,其中0表示最小值,f表示最大值。 The next two digits represent the green and blue channels, respectively, in the same way.
接下来的两位数字以相同的方式分别代表绿色和蓝色通道。 The alpha channel of the color is fully opaque.
颜色的Alpha通道是完全不透明的。 This syntax is often explained by saying that it's identical to a 6-digit notation obtained by "duplicating" all of the digits.
通常通过说它与通过“复制”所有数字获得的6位数字表示法相同来解释该语法。 For example, the notation #123 specifies the same color as the notation #112233.
例如,符号#123指定与符号#112233相同的颜色。 This method of specifying a color has lower "resolution" than the 6-digit notation;
这种指定颜色的方法的“分辨率”低于6位数字的表示法。 there are only 4096 possible colors expressible in the 3-digit hex syntax, as opposed to approximately 17 million in 6-digit hex syntax.
3位十六进制语法中只能显示4096种可能的颜色,而6位十六进制语法中大约有1,700万种颜色。
4 digits
4位数
This is a shorter variant of the 8-digit notation, "expanded" in the same way as the 3-digit notation is.这是8位数字表示法的较短变体,以与3位数字表示法相同的方式“扩展”。 The first digit, interpreted as a hexadecimal number, specifies the red channel of the color, where 0 represents the minimum value and f represents the maximum.
第一位解释为十六进制数字,指定该颜色的红色通道,其中0表示最小值,f表示最大值。 The next three digits represent the green, blue, and alpha channels, respectively.
接下来的三个数字分别代表绿色,蓝色和Alpha通道。
Now I already know how to convert a UIColor
object to a 6-digits hex string. 现在,我已经知道如何将
UIColor
对象转换为6位十六进制字符串。 But I'm not sure how to convert it to a 3-digits/4-digits/8-digits hex string and what should be noticed. 但是我不确定如何将其转换为3位数/ 4位数/ 8位数的十六进制字符串以及应注意的事项。
guard let components = cgColor.components, components.count >= 3 else {
return nil
}
let r = Float(components[0])
let g = Float(components[1])
let b = Float(components[2])
var a = Float(1.0)
if components.count >= 4 {
a = Float(components[3])
}
if alpha {
// rrggbbaa mode
// is there any difference between rrggbbaa and aarrggbb?
return String(format: "%02lX%02lX%02lX%02lX", lroundf(r * 255), lroundf(g * 255), lroundf(b * 255), lroundf(a * 255))
} else {
// rrggbb mode
return String(format: "%02lX%02lX%02lX", lroundf(r * 255), lroundf(g * 255), lroundf(b * 255))
}
NOTE: it's UIColor
to string, not string to UIColor
注意:它是字符串的
UIColor
,而不是UIColor
字符串
Here's an extension for UIColor
that can provide hexStrings in many formats including 3, 4, 6, and 8 digit forms: 这是
UIColor
的扩展,可以提供多种格式的hexString,包括3、4、6和8位数字形式:
extension UIColor {
enum HexFormat {
case RGB
case ARGB
case RGBA
case RRGGBB
case AARRGGBB
case RRGGBBAA
}
enum HexDigits {
case d3, d4, d6, d8
}
func hexString(_ format: HexFormat = .RRGGBBAA) -> String {
let maxi = [.RGB, .ARGB, .RGBA].contains(format) ? 16 : 256
func toI(_ f: CGFloat) -> Int {
return min(maxi - 1, Int(CGFloat(maxi) * f))
}
var r: CGFloat = 0
var g: CGFloat = 0
var b: CGFloat = 0
var a: CGFloat = 0
self.getRed(&r, green: &g, blue: &b, alpha: &a)
let ri = toI(r)
let gi = toI(g)
let bi = toI(b)
let ai = toI(a)
switch format {
case .RGB: return String(format: "#%X%X%X", ri, gi, bi)
case .ARGB: return String(format: "#%X%X%X%X", ai, ri, gi, bi)
case .RGBA: return String(format: "#%X%X%X%X", ri, gi, bi, ai)
case .RRGGBB: return String(format: "#%02X%02X%02X", ri, gi, bi)
case .AARRGGBB: return String(format: "#%02X%02X%02X%02X", ai, ri, gi, bi)
case .RRGGBBAA: return String(format: "#%02X%02X%02X%02X", ri, gi, bi, ai)
}
}
func hexString(_ digits: HexDigits) -> String {
switch digits {
case .d3: return hexString(.RGB)
case .d4: return hexString(.RGBA)
case .d6: return hexString(.RRGGBB)
case .d8: return hexString(.RRGGBBAA)
}
}
}
Examples 例子
print(UIColor.red.hexString(.d3)) // #F00
print(UIColor.red.hexString(.d4)) // #F00F
print(UIColor.red.hexString(.d6)) // #FF0000
print(UIColor.red.hexString(.d8)) // #FF0000FF
print(UIColor.green.hexString(.RGB)) // #0F0
print(UIColor.green.hexString(.ARGB)) // #F0F0
print(UIColor.green.hexString(.RGBA)) // #0F0F
print(UIColor.green.hexString(.RRGGBB)) // #00FF00
print(UIColor.green.hexString(.AARRGGBB)) // #FF00FF00
print(UIColor.green.hexString(.RRGGBBAA)) // #00FF00FF
print(UIColor(red: 0.25, green: 0.5, blue: 0.75, alpha: 0.3333).hexString()) // #4080c055
Any UIColor
instance can be represented by 8 hexadecimal digits: for example #336699CC
. 任何
UIColor
实例都可以由8个十六进制数字表示:例如#336699CC
。 For some colours, a shorter representation can be used: 对于某些颜色,可以使用较短的表示形式:
#336699FF
becomes #336699
#336699FF
变为#336699
#336699CC
becomes #369C
, but #335799CC
cannot be shortened #336699CC
变为#369C
,但#335799CC
无法缩短 #336699FF
becomes #369
#336699FF
变为#369
The following function will return the shortest valid representation allowed for a given UIColor
. 以下函数将返回给定
UIColor
允许的最短有效表示形式。
struct HexRepresentationOptions: OptionSet {
let rawValue: UInt
static let allowImplicitAlpha = HexRepresentationOptions(rawValue: 1 << 0)
static let allowShortForm = HexRepresentationOptions(rawValue: 1 << 1)
static let allowAll: HexRepresentationOptions = [
.allowImplicitAlpha,
.allowShortForm
]
}
func hexRepresentation(forColor color: UIColor,
options: HexRepresentationOptions = .allowAll) -> String? {
var red: CGFloat = 0.0
var green: CGFloat = 0.0
var blue: CGFloat = 0.0
var alpha: CGFloat = 0.0
guard color.getRed(&red, green: &green, blue: &blue, alpha: &alpha) else {
return nil
}
let colorComponents: [CGFloat]
if options.contains(.allowImplicitAlpha) && alpha == 1.0 {
colorComponents = [red, green, blue]
} else {
colorComponents = [red, green, blue, alpha]
}
let hexComponents = colorComponents.map { component -> (UInt8, UInt8, UInt8) in
let hex = UInt8(component * 0xFF)
return (hex, hex & 0x0F, hex >> 4)
}
let hasAlpha = colorComponents.count == 4
let useShortForm = options.contains(.allowShortForm) &&
!hexComponents.contains(where: { c in c.1 != c.2 })
let hexColor: UInt64 = hexComponents.reduce(UInt64(0)) { result, component in
if useShortForm {
return (result << 4) | UInt64(component.1)
} else {
return (result << 8) | UInt64(component.0)
}
}
switch (useShortForm, hasAlpha) {
case (true, false):
return String(format: "#%03X", hexColor)
case (true, true):
return String(format: "#%04X", hexColor)
case (false, false):
return String(format: "#%06X", hexColor)
case (false, true):
return String(format: "#%08X", hexColor)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.