orgColor
。overlayColor
且具有透明性(alpha通道)的覆盖UIView覆盖的。给出这两种颜色orgColor
和overlayColor
,我该如何计算{strong>不具有任何透明度但在屏幕上完全相同的颜色calculatedColor
好像两个视图都会被覆盖?
我为此编写了一个骨架函数(以展示其原理)。但是不知道如何计算(我在堆栈上发现了几篇有关颜色融合的文章,但实际上并没有消除结果的透明度...):
func calculateColor(orgColor: UIColor, overlayColor: UIColor) -> UIColor {
var (r1, g1, b1, a1) = (CGFloat(0), CGFloat(0), CGFloat(0), CGFloat(0))
var (r2, g2, b2, a2) = (CGFloat(0), CGFloat(0), CGFloat(0), CGFloat(0))
orgColor.getRed(&r1, green: &g1, blue: &b1, alpha: &a1)
overlayColor.getRed(&r2, green: &g2, blue: &b2, alpha: &a2)
//how to put the alpha in the r g b? and integrate the overlay r g b?
return color
}
答案 0 :(得分:1)
覆盖颜色的Alpha(a2
)告诉您颜色占总数的百分比,(1 - a2)
告诉您原始颜色所占的百分比。因此,这是一个简单的计算:
func calculateColor(orgColor: UIColor, overlayColor: UIColor) -> UIColor {
// Helper function to clamp values to range (0.0 ... 1.0)
func clampValue(_ v: CGFloat) -> CGFloat {
guard v > 0 else { return 0 }
guard v < 1 else { return 1 }
return v
}
var (r1, g1, b1, a1) = (CGFloat(0), CGFloat(0), CGFloat(0), CGFloat(0))
var (r2, g2, b2, a2) = (CGFloat(0), CGFloat(0), CGFloat(0), CGFloat(0))
orgColor.getRed(&r1, green: &g1, blue: &b1, alpha: &a1)
overlayColor.getRed(&r2, green: &g2, blue: &b2, alpha: &a2)
// Make sure the input colors are well behaved
// Components should be in the range (0.0 ... 1.0)
r1 = clampValue(r1)
g1 = clampValue(g1)
b1 = clampValue(b1)
r2 = clampValue(r2)
g2 = clampValue(g2)
b2 = clampValue(b2)
a2 = clampValue(a2)
let color = UIColor( red: r1 * (1 - a2) + r2 * a2,
green: g1 * (1 - a2) + g2 * a2,
blue: b1 * (1 - a2) + b2 * a2,
alpha: 1)
return color
}
直觉上,这可以签出。如果覆盖颜色完全不透明(a2 == 1
),则结果将是覆盖颜色。如果覆盖颜色是完全透明的(a2 == 0
),则结果将是原始颜色。如果重叠色的Alpha为0.5
,则您将获得恰好介于两种颜色中间的混合色。
在操场上对其进行测试:
// Make these colors anything you want
let c1 = UIColor(red: 27/255, green: 155/255, blue: 199/255, alpha: 1.0)
let c2 = UIColor(red: 188/255, green: 13/255, blue: 51/255, alpha: 0.37)
let c3 = calculateColor(orgColor: c1, overlayColor: c2)
let view1 = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
let view2 = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
view1.backgroundColor = c1
view2.backgroundColor = c2
// Overlay view2 onto view1
view1.addSubview(view2)
// view3 has the calculated color
let view3 = UIView(frame: CGRect(x: 100, y: 0, width: 100, height: 100))
view3.backgroundColor = c3
// display the views side by side in view4
let view4 = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 100))
view4.addSubview(view1)
view4.addSubview(view3)
// display this view and see that the two halves match
view4
游乐场输出:
答案 1 :(得分:1)
基于@vacawama的回答(全部归功于他!),我为UIColor编写了以下扩展名:
extension UIColor {
func solidColorWhenOverlayed(by overlayColor: UIColor) -> UIColor {
// Helper function to clamp values to range (0.0 ... 1.0)
func clampValue(_ v: CGFloat) -> CGFloat {
guard v > 0 else { return 0 }
guard v < 1 else { return 1 }
return v
}
var (r1, g1, b1, a1) = (CGFloat(0), CGFloat(0), CGFloat(0), CGFloat(0))
var (r2, g2, b2, a2) = (CGFloat(0), CGFloat(0), CGFloat(0), CGFloat(0))
getRed(&r1, green: &g1, blue: &b1, alpha: &a1)
overlayColor.getRed(&r2, green: &g2, blue: &b2, alpha: &a2)
// Make sure the input colors are well behaved
// Components should be in the range (0.0 ... 1.0)
// This to compensate for any "bad" colors = colors which have component values out of range
r1 = clampValue(r1)
g1 = clampValue(g1)
b1 = clampValue(b1)
r2 = clampValue(r2)
g2 = clampValue(g2)
b2 = clampValue(b2)
a2 = clampValue(a2)
return UIColor( red : r1 * (1 - a2) + r2 * a2,
green: g1 * (1 - a2) + g2 * a2,
blue : b1 * (1 - a2) + b2 * a2,
alpha: 1)
}
}