在Swift中混合使用UIColors
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Swift中混合使用UIColors相关的知识,希望对你有一定的参考价值。
我有两个SKSpriteNode,它们的颜色定义如下:
colorNode[0].color = UIColor(red: 255, green: 0, blue: 0, alpha: 1)
colorNode[1].color = UIColor(red: 0, green: 255, blue: 0, alpha: 1)
我想让第三个SKSpriteNode用前两个的混合着色,结果应该是这样的:
colorNode[2].color = UIColor(red: 255, green: 255, blue: 0, alpha: 1)
但有没有办法添加两个UIColors?像这样 :
colorNode[2].color = colorNode[0].color + colorNode[1].color
答案
这样的事情怎么样:
func addColor(_ color1: UIColor, with color2: 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))
color1.getRed(&r1, green: &g1, blue: &b1, alpha: &a1)
color2.getRed(&r2, green: &g2, blue: &b2, alpha: &a2)
// add the components, but don't let them go above 1.0
return UIColor(red: min(r1 + r2, 1), green: min(g1 + g2, 1), blue: min(b1 + b2, 1), alpha: (a1 + a2) / 2)
}
func multiplyColor(_ color: UIColor, by multiplier: CGFloat) -> UIColor {
var (r, g, b, a) = (CGFloat(0), CGFloat(0), CGFloat(0), CGFloat(0))
color.getRed(&r, green: &g, blue: &b, alpha: &a)
return UIColor(red: r * multiplier, green: g * multiplier, blue: b * multiplier, alpha: a)
}
定义运算符以添加颜色并将颜色乘以Double
:
func +(color1: UIColor, color2: UIColor) -> UIColor {
return addColor(color1, with: color2)
}
func *(color: UIColor, multiplier: Double) -> UIColor {
return multiplyColor(color, by: CGFloat(multiplier))
}
然后你可以混合这样的颜色:
// Make orange with 50% red and 50% yellow
let orange = .red * 0.5 + .yellow * 0.5
// Make light gray with 25% black and 75% white
let lightGray = .black * 0.25 + .white * 0.75
// Make sky blue by lightening a combination of 25% blue and 75% cyan
let skyBlue = (.blue * 0.25 + .cyan * 0.75) * 0.25 + .white * 0.75
// Make dark red by combining 50% red and 50% black
let darkRed = .red * 0.50 + .black * 0.50
// Make purple from 60% blue and 40% red
let purple = (.blue * 0.60 + .red * 0.40)
// Then make lavender from 25% purple and 75% white
let lavender = purple * 0.25 + .white * 0.75
另一答案
Swift3版本,作为扩展,带有更多防护和细粒度调整:
extension UIColor {
static func blend(color1: UIColor, intensity1: CGFloat = 0.5, color2: UIColor, intensity2: CGFloat = 0.5) -> UIColor {
let total = intensity1 + intensity2
let l1 = intensity1/total
let l2 = intensity2/total
guard l1 > 0 else { return color2}
guard l2 > 0 else { return color1}
var (r1, g1, b1, a1): (CGFloat, CGFloat, CGFloat, CGFloat) = (0, 0, 0, 0)
var (r2, g2, b2, a2): (CGFloat, CGFloat, CGFloat, CGFloat) = (0, 0, 0, 0)
color1.getRed(&r1, green: &g1, blue: &b1, alpha: &a1)
color2.getRed(&r2, green: &g2, blue: &b2, alpha: &a2)
return UIColor(red: l1*r1 + l2*r2, green: l1*g1 + l2*g2, blue: l1*b1 + l2*b2, alpha: l1*a1 + l2*a2)
}
}
另一答案
代码已经实现了photoshop的所有图层混合。如果对你有用。别忘了给我一个开始。玩得开心〜
GitHub上:https://github.com/Orange-W/PhotoshopBending
import Foundation
import UIKit
extension UIColor {
// MARK: - 常用叠图
// Alpha Blending 前景色叠图
func blendAlpha(coverColor: UIColor) -> UIColor {
let c1 = coverColor.rgbaTuple()
let c2 = self.rgbaTuple()
let c1r = CGFloat(c1.r)
let c1g = CGFloat(c1.g)
let c1b = CGFloat(c1.b)
let c2r = CGFloat(c2.r)
let c2g = CGFloat(c2.g)
let c2b = CGFloat(c2.b)
// 前景色叠图公式
let r = c1r * c1.a + c2r * (1 - c1.a)
let g = c1g * c1.a + c2g * (1 - c1.a)
let b = c1b * c1.a + c2b * (1 - c1.a)
return UIColor.init(red: r/255.0, green: g/255.0, blue: b/255.0, alpha: 1.0)
}
// MARK: - 去亮度型
/// Darken 变暗 B<=A: C=B; B>=A: C=A
func blendDarken(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {
return blendProcedure(coverColor: coverColor, alpha: alpha) { return ($0 <= $1) ? $0 : $1 }
}
/// Multiply 正片叠底 C = A*B
func blendMultiply(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {
return blendProcedure(coverColor: coverColor, alpha: alpha) { return $0 * $1 }
}
/// Color Burn 颜色加深 C=1-(1-B)/A
func blendColorBurn(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {
return blendProcedure(coverColor: coverColor, alpha: alpha) { return 1 - (1 - $0) / $1 }
}
/// Linear Burn 线性加深 C=A+B-1
func blendLinearBurn(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {
return blendProcedure(coverColor: coverColor, alpha: alpha) { return ($1 + $0) - 1.0 }
}
// MARK: - 去暗型
/// Lighten 变亮 B>=A: C=B; B<=A: C=A
func blendLighten(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {
return blendProcedure(coverColor: coverColor, alpha: alpha) { return ($0 >= $1) ? $0 : $1 }
}
/// Screen 滤色 C=1-(1-A)*(1-B), 也可以写成 1-C=(1-A)*(1-B)
func blendScreen(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {
return blendProcedure(coverColor: coverColor, alpha: alpha) { return 1 - (1 - $1) * (1 - $0) }
}
/// Color Dodge 颜色减淡 C=B/(1-A)
func blendColorDodge(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {
return blendProcedure(coverColor: coverColor, alpha: alpha) {
if $1 >= 1.0 { return $1 }
else { return min(1.0, $0 / (1 - $1)) }
}
}
/// Linear Dodge 线性减淡 C=A+B
func blendLinearDodge(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {
return blendProcedure(coverColor: coverColor, alpha: alpha) { return min(1, $1 + $0) }
}
// MARK: - 溶合型
/// Overlay 叠加 B<=0.5: C=2*A*B; B>0.5: C=1-2*(1-A)*(1-B)
func blendOverlay(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {
return blendProcedure(coverColor: coverColor, alpha: alpha) {
if $0 <= 0.5 { return 2 * $1 * $0 }
else { return 1 - 2 * (1 - $1) * (1 - $0) }
}
}
/// Soft Light 柔光 A<=0.5: C=(2*A-1)*(B-B*B)+B; A>0.5: C=(2*A-1)*(sqrt(B)-B)+B
func blendSoftLight(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {
return blendProcedure(coverColor: coverColor, alpha: alpha) {
if $1 <= 0.5 { return (2 * $1 - 1) * ($0 - $0 * $0) + $0 }
else { return (2 * $1 - 1)*( sqrt($0) - $0) + $0 }
}
}
/// Hard Light 强光 A<=0.5: C=2*A*B; A>0.5: C=1-2*(1-A)*(1-B)
func blendHardLight(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {
return blendProcedure(coverColor: coverColor, alpha: alpha) {
if $1 <= 0.5 { return 2 * $1 * $0 }
else { return 1 - 2 * (1 - $1) * (1 - $0) }
}
}
/// Vivid Light 亮光 A<=0.5: C=1-(1-B)/(2*A); A>0.5: C=B/(2*(1-A))
func blendVividLight(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {
return blendProcedure(coverColor: coverColor, alpha: alpha) {
if $1 <= 0.5 { return self.fitIn((1 - (1 - $0) / (2 * $1)), ceil: 1.0) }
else { return self.fitIn($0 / (2 * (1 - $1)), ceil: 1.0) }
}
}
/// Linear Light 线性光 C=B+2*A-1
func blendLinearLight(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {
return blendProcedure(coverColor: coverColor, alpha: alpha) { return self.fitIn($0 + 2 * $1 - 1, ceil: 1.0) }
}
/// Pin Light 点光
/// B<2*A-1: C=2*A-1
/// 2*A-1<B<2*A: C=B
/// B>2*A: C=2*A
func blendPinLight(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {
return blendProcedure(coverColor: coverColor, alpha: alpha) {
if $0 <= 2 * $1 - 1 { return 2 * $1 - 1 }
else if (2 * $1 - 1 < $0) && ($0 < 2 * $1) { return $0}
else { return 2 * $1 }
}
}
/// Hard Mix 实色混合A<1-B: C=0; A>1-B: C=1
func blendHardMix(coverColor: UIColor,alpha: CGFloat = 1.0) -> UIColor {
return blendProcedure(coverColor: coverColor, alpha以上是关于在Swift中混合使用UIColors的主要内容,如果未能解决你的问题,请参考以下文章
比较两个 UIColors(点击 UIImageView 中的位置与资产目录颜色)
错误记录Flutter 混合开发获取 BinaryMessenger 报错 ( FlutterActivityAndFragmentDelegate.getFlutterEngine() )(代码片段