我希望在C ++ / RealBasic中实现一个函数,通过参数创建颜色渐变:
以下链接显示了所需输出图像的一些示例: http://www.artima.com/articles/linear_gradients_in_flex_4.html,http://i.stack.imgur.com/4ssfj.png
我找到了多个例子,但它们只给我垂直和水平渐变,而我也想指定角度和强度。
有人能帮助我吗?
P.S。:我对几何学只知道一点!! :(
答案 0 :(得分:0)
你的问题非常广泛,因为这是一个非常复杂的练习,包含大量代码,包括图像渲染,图像格式处理,将文件写入磁盘等。这些都不是单一功能的问题。因此,我专注于制作2种颜色的任意线性颜色渐变。
线性颜色渐变
您可以在两种颜色之间通过linear interpolation创建线性颜色“渐变”。然而,简单的线性插值使得转换看起来非常恶劣。对于视觉上更具吸引力的结果,我建议使用某种S-shaped插值曲线,例如基于Hermite插值的smoothstep。
关于角度,您可以通过颜色渐变的起点(p0
)和结束点(p1
)定义线段。我们称之为d01
之间的距离,d01 = distance(p0, p1)
。然后,对于图像的每个像素点p
,您必须计算此段上的最近点p2
。 Here is an example如何做到这一点。然后计算t = distance(p0, p2) / d01
。这将是[0,1]范围内的 lerp 参数t
。
通过此t
在2渐变颜色之间插值,您获得给定点p
的颜色。
这可以通过多种方式实现。您可以使用OpenGL渲染图像,然后将像素缓冲区读回RAM。如果您不熟悉OpenGL或渲染过程,可以编写一个获取点(像素的2D坐标)并返回RGB颜色的函数 - 这样您就可以计算图像的所有像素。最后,您可以使用图像格式将图像写入磁盘,但这是另一个故事。
以下是上述某些功能的示例C ++ 14实现。
简单线性插值:
template <typename T, typename U>
T lerp(const T &a, const T &b, const U &t)
{
return (U(1) - t)*a + t*b;
}
,其中a
和b
是两个值(在这种情况下为颜色),您希望在它们之间进行插值,t
是范围[0,1]中的插值参数表示a
和b
之间的转换。
当然上面的函数需要一个类型T
,它支持乘以标量。您可以简单地使用任何3D矢量类型,因为颜色实际上是颜色空间中的坐标。
两个2D点之间的距离:
#include <cmath>
auto length(const Point2 &p)
{
return std::sqrt(p.x*p.x + p.y*p.y);
}
auto distance(const Point2 &a, const Point2 &b)
{
Point delta = b - a;
return length(delta);
}
来自https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient的图片