use*_*679 10 c++ openframeworks
我试图将一种颜色插入到另一种相同颜色的阴影中.(例如:天蓝色至深蓝色然后返回).
我偶然发现了一些代码,如果范围是0-255或0-1,可以使用.但是,就我而言,我有Color1和Color2的RGB代码,并希望进行旋转.
颜色1:151,206,255
颜色2:114,127,157
任何想法如何去做?
Car*_*los 19
我知道这有点旧,但如果有人在寻找它,那是值得的.
首先,你可以在任何颜色空间中进行插值,包括RGB,在我看来,这是最简单的颜色之一.
假设变化将由0和1之间的分数值(例如0.3)控制,其中0表示全色1,1表示全色2.
理论:
Result = (color2 - color1) * fraction + color1
Run Code Online (Sandbox Code Playgroud)
应用:
由于RGB有3个通道(红色,绿色和蓝色),我们必须为每个通道执行此数学运算.
使用您的示例颜色:
color1: 151,206,255
color2: 114,127,157
R = (114-151) * fraction + 151
G = (127-206) * fraction + 206
B = (157-255) * fraction + 255
Run Code Online (Sandbox Code Playgroud)
很简单!
Syn*_*xis 10
将RGB颜色转换为HSV,然后插入每个组件(不仅是颜色,请参阅答案结束),之后您可以转换回RGB.
您可以进行RGB插值,但HSV的结果更好,因为在此空间中颜色与亮度和饱和度分开(维基百科关于HSV的文章).HSV插值比RGB插值更"逻辑",因为后者可以在插值时获得额外的颜色.
插值的一些代码:
template<typename F>
ColorRGB interpolate(ColorRGB a, ColorRGB b, float t, F interpolator)
{
// 0.0 <= t <= 1.0
ColorHSV ca = convertRGB2HSV(a);
ColorHSV cb = convertRGB2HSV(b);
ColorHSV final;
final.h = interpolator(ca.h, cb.h, t);
final.s = interpolator(ca.s, cb.s, t);
final.v = interpolator(ca.v, cb.v, t);
return convertHSV2RGB(final);
}
int linear(int a, int b, float t)
{
return a * (1 - t) + b * t;
}
// use: result = interpolate(color1,color2,ratio,&linear);
Run Code Online (Sandbox Code Playgroud)
我建议你将RGB转换为HSV,然后调整其组件,然后转换回RGB.
将RGB转换为HSV和HSV转换为RGB的算法,范围为0-255
许多框架也有转换函数,例如Qt有QColor类.
但问题是关于实际插值...这里是一个简单的插值函数:
// 0 <= stepNumber <= lastStepNumber
int interpolate(int startValue, int endValue, int stepNumber, int lastStepNumber)
{
return (endValue - startValue) * stepNumber / lastStepNumber + startValue;
}
Run Code Online (Sandbox Code Playgroud)
因此,在循环中调用您想要插入的所有颜色分量.使用RBG插值,您需要插入每个组件,在其他一些颜色空间中,您可能只需插入一个.
用于视觉效果的最佳色彩空间是HCL。这是一个专门为在遍历其维度时看起来不错而创建的空间,其中“看起来不错”与光或墨水的任何物理属性无关,分别如 RGB 和 CMYK。
使用 HCL 是昂贵的,所以最好的办法是在这个空间中创建一些中间值,然后在原生的 RGB 中进行插值。这就是我在我的动画引擎中所做的。
这是它的一个片段,在 Swift 4.0 中
extension UIColor {
typealias Components = (CGFloat, CGFloat, CGFloat, CGFloat)
enum Space: String {
case RGB = "RGB"
case HSB = "HSB"
case HCL = "HCL"
}
func components(in space: UIColor.Space) -> Components {
switch space {
case .RGB: return self.rgba // var defined in HandyUIKit's extension
case .HSB: return self.hsba // var defined in HandyUIKit's extension
case .HCL: return self.hlca // var defined in HandyUIKit's extension
}
}
func spectrum(to tcol: UIColor, for space: UIColor.Space) -> [UIColor] {
var spectrum = [UIColor]()
spectrum.append(self)
let fcomps = self.components(in: space)
let tcomps = tcol.components(in: space)
for i in 0 ... 5 {
let factor = CGFloat(i) / 5.0
let comps = (1.0 - factor) * fcomps + factor * tcomps
let color = UIColor(with: comps, in: space)
spectrum.append(color)
}
spectrum.append(tcol)
return spectrum
}
convenience init(with components: Components, in space: Space) {
switch space {
case .RGB: self.init(red: components.0, green: components.1, blue: components.2, alpha: components.3)
case .HSB: self.init(hue: components.0, saturation: components.1, brightness: components.2, alpha: components.3)
case .HCL: self.init(hue: components.0, luminance: components.1, chroma: components.2, alpha: components.3)
}
}
}
func *(lhs:CGFloat, rhs:UIColor.Components) -> UIColor.Components {
return (lhs * rhs.0, lhs * rhs.1, lhs * rhs.2, lhs * rhs.3)
}
func +(lhs:UIColor.Components, rhs:UIColor.Components) -> UIColor.Components {
return (lhs.0 + rhs.0, lhs.1 + rhs.1, lhs.2 + rhs.2, lhs.3 + rhs.3)
}
Run Code Online (Sandbox Code Playgroud)
引擎和上面的示例都使用HandyUIKit进行空间之间的转换,因此请将此项目添加到您正在构建的任何内容中,以使上述代码工作。
| 归档时间: |
|
| 查看次数: |
28267 次 |
| 最近记录: |