65.9K
CodeProject 正在变化。 阅读更多。
Home

用 C# 创建自定义颜色渐变

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.71/5 (11投票s)

2007年3月27日

CPOL

5分钟阅读

viewsIcon

76569

downloadIcon

1314

本文展示了如何创建自定义颜色渐变。

引言

在我之前的文章(有关更多信息,请访问 www.publishing.unicadinc.com)中,我向您展示了如何通过将 y 数据与颜色映射矩阵的索引关联起来绘制颜色条。在某些图形应用程序中,您可能希望根据给定的颜色数据直接映射曲面对象的颜色。在本文中,我将向您展示如何创建这种自定义颜色着色。

背景

考虑一个涉及名为“Jet”的颜色映射矩阵的情况,如上一个项目中的 ColorMap 类中定义的,默认颜色映射长度为 64。假设我们有一个 3x3 的颜色数据矩阵

在这种情况下,颜色数据的最大值和最小值分别为 4 和 -3。我们可以使用上一篇文章中给出的公式轻松确定颜色映射索引号

到目前为止,我们还没有提供 x 和 y 坐标数据。我们认为沿行(x 数据)和列(y 数据)的颜色数据值指定了 9 个顶点,其中每组相邻的四个元素通过四边形连接。如图 1 所示,就颜色数据矩阵中的元素而言,有四个四边形。您可能想知道为什么在只有四个四边形的情况下,我们需要颜色映射中的九个索引。对于曲面对象,可以为每个顶点分配颜色。这允许您对四个顶点颜色执行双线性插值,以确定四边形内任何点的颜色。

图 1:颜色矩阵和颜色映射。

如果您不想使用颜色插值,颜色数据也可以是 2x2 矩阵,如图 1 中圈出的元素所示。基本上,您可以取左上角顶点的颜色数据来填充相应的四边形。将其与颜色索引结合,您将获得这四个四边形的直接颜色映射,如图 1 的右侧所示。

您可以看到,颜色在不同四边形之间的变化非常剧烈。为了获得更好的颜色着色效果,您需要执行双线性颜色插值。双线性插值使用每个四边形周围的四个顶点值来获取四边形内的任何值。假设您想获取 (x, y) 的值,并且四边形的顶点位于 (x0, y0)、(x1, y0)、(x0, y1) 和 (x1, y1),其中它们分别具有颜色数据值 C00、C10、C01 和 C11,如图 2 所示

图 2:用于双线性插值的坐标。

在顶部邻居行上,在 (x0, y0) 和 (x1, y0) 之间进行线性插值,将 C0 在 (x, y0) 的值估计为

同样,在底部邻居行上,在 (x0, y1) 和 (x1, y1) 之间进行线性插值,将 C1 在 (x, y1) 的值估计为

最后,在 C0 和 C1 之间进行线性插值,将 C 在 (x, y) 的值估计为

通过将 C0 和 C1 的表达式代入上述方程,我们得到

您可以看到 C 的方程是一个涉及 x 和 y 的幂次不超过 1 的多项式,并且有四个系数:C = a1+ a2*x + a3*y + a4*x*y。因为这四个系数是由四个值(C00、C01、C10 和 C11)确定的,所以它们通常由数据唯一确定。这立即意味着,先沿列(y 方向)插值,然后对结果沿 x 方向插值的可比过程将给出相同的结果,因为它也将有一个类似的唯一解的公式。

请注意,“双线性”一词来源于线性插值过程(在一个方向上两次,然后一次在垂直方向上),而不是来自 C 的公式。该公式包含一个 x * y 项,这不是线性的。

我们现在可以使用上述方程来实现颜色着色。您需要将上一个文章中的 ColorMap 类以及一个名为 PointC 的新点类添加到当前项目中。PointC 包含颜色数据和 ARGB 数组。这是它的代码列表

using System; 
using System.Drawing; 
using System.Drawing.Drawing2D; 
namespace Example1_9 
{ 
    public class PointC 
    { 
        public PointF pointf = new PointF(); 
        public float C = 0; 
        public int[] ARGBArray = new int[4]; 
        public PointC() 
        { 
        } 
        public PointC(PointF ptf, float c) 
        { 
            pointf = ptf; 
            C = c; 
        } 
        public PointC(PointF ptf, float c, int[] argbArray) 
        { 
            pointf = ptf; 
            C = c; 
            ARGBArray = argbArray; 
        } 
    } 
} 

这个类非常简单;我们只是将颜色数据和 ARGB 数组与点关联起来。

其余所有代码均在 Form1 类中实现。Form1 类中的 Interp 方法以给定的四边形的四个顶点点和相应的颜色数据值为输入,并使用双线性插值方法在四边形内插值颜色数据值。颜色着色质量由插值点的数量 npoints 控制。

DrawObjects 方法中,我们首先使用直接映射方法绘制对象,然后通过调用 Interp 方法使用双线性插值绘制对象。

Using the Code

随附的 ZIP 文件包含所有源代码和二进制文件,这些文件是在 Visual Studio 2005 上构建的。运行项目会生成输出,如图 3 所示

图 3:直接(左)和插值(右)颜色映射。

双线性插值颜色映射在图像处理和 3D 曲面图应用程序中得到了广泛应用。

本项目摘自新书《实用 C# 图表和图形》的示例(第 1 章中的示例 1-9),您可以在其中找到更多用于实际 .NET 应用程序的高级图表和图形编程。有关更多信息,请访问网站。

关于作者

Jack Xu 博士拥有理论物理学博士学位。他在 Basic、Fortran、C、C++、Matlab 和 C# 方面拥有超过 15 年的编程经验,专注于数值计算方法、算法、物理建模、计算机辅助设计(CAD)开发、图形用户界面和 3D 图形。目前,他负责开发基于 Microsoft .NET Framework 的商业 CAD 工具。

请阅读我的其他文章

© . All rights reserved.