.NET 中的热图样式渐变

Heatmap style gradients in .NET

我正在尝试创建一个具有类似于此的渐变的热图:

这张图片显示了三个点,渐变很好地融合在一起。

这是我目前在绘图功能中所做的事情:

public void DrawGradient(int x, int y, Graphics g) {
    using (var ellipsePath = new GraphicsPath()) {

    var bounds = new Rectangle(x, y, 100, 100);
    ellipsePath.AddEllipse(bounds);
    var brush = new PathGradientBrush(ellipsePath);
    Color[] colors = { 
           Color.FromArgb(64, 0, 0, 255), 
           Color.FromArgb(140, 0, 255, 0), 
           Color.FromArgb(216, 255, 255, 0), 
           Color.FromArgb(255, 255, 0, 0) 
       };
    float[] relativePositions = {0f,0.25f,0.5f, 1.0f};
    ColorBlend colorBlend = new ColorBlend();
    colorBlend.Colors = colors;
    colorBlend.Positions = relativePositions;
    brush.InterpolationColors = colorBlend;

    g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;
    g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
    g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;

    g.FillEllipse(brush, bounds);
  }
}

为两个重叠点创建这样的图像:

它不混合。如何在 .NET 绘图中创建渐变混合效果?

是的,这可以通过 < 100 行 .NET 和 GDI+ 绘图代码实现。:

您需要在代码中更改这些内容:

  • 您需要将点区域淡化为透明,这样您就可以添加它们
  • 您需要使用灰度渐变,这样您就不会创建错误的、可能是浑浊的颜色
  • 因此您需要重新映射颜色。

详情如下:

你需要两个渐变:

  • 灰阶从黑色(255,0,0,0)到透明黑色(0,0,0,0)。您可以通过使透明端淡出得更快或更慢来影响平滑度。

  • 颜色渐变枚举了您的热图颜色。

接下来您需要一张或多张带有模糊灰色圆圈的位图。如果点区域都一样,一个就可以了..

现在您可以将位图绘制到目标位图上了。确保设置 Graphics.CompositingMode = CompositingMode.SourceOver; 这会产生类似左侧屏幕截图的结果。

最后你需要 Remap 颜色:

为此,您需要设置 ColorMaps:

  • 创建两个颜色列表,一个以 256 个步骤遍历灰度颜色,一个以相同的步骤遍历热图颜色。请注意,列表必须具有相同数量的元素;然而,渐变在 ColorBlend.Colors 中可以有任意多或少。

颜色列表可以通过使用 LinearGradientBrush 填充 256x1 像素 Bitmap 来创建,该 LinearGradientBrush 使用相同的两个 ColorBlends 然后使用 GetPixel 拉出颜色..

完成 SetRemapTable 之后,我们终于可以绘制热图了,瞧,正确的屏幕截图非常相似,即使没有任何调整以真正接近您的热图。

您的代码

以下是对您代码中的缺陷的几点评论:

  • 您需要从完全透明淡入。您的颜色以 64 的 alpha 开头,与 'almost transparent' 相差 far。我们的眼睛在天平的这一端非常敏感!

这里是我用的灰度渐变,有photoshop风格的棋盘背景,所以你可以看到透明度:

  • 您的颜色的另一个问题是它们以蓝色开头;他们真的需要从白色开始!

  • 最根本的问题是颜色的调和。对于 'heat map',(或 'profile map' 或 'displacement map'),我们需要 加起来 值,而不是混合它们。为此,颜色通道是无用的。颜色是圆形的,它们自然不会适合升序值列表。如果我们只使用 alpha 通道,我们可以以一种简单的方式将贴图限制为 'brightness map',然后我们可以按照我们喜欢的任何方式对其进行着色..

请注意,我假设中心点是最大值。如果不是,您需要将它们缩小到较低的 alpha,以便将它们加起来不会溢出..

另请注意,对于非常重要的应用,例如 医学科学 成像,您应该一直到 计算值,因此您可以完全控制映射!