.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,以便将它们加起来不会溢出..
另请注意,对于非常重要的应用,例如 医学 或 科学 成像,您应该一直到 计算值,因此您可以完全控制映射!
我正在尝试创建一个具有类似于此的渐变的热图:
这张图片显示了三个点,渐变很好地融合在一起。
这是我目前在绘图功能中所做的事情:
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,以便将它们加起来不会溢出..
另请注意,对于非常重要的应用,例如 医学 或 科学 成像,您应该一直到 计算值,因此您可以完全控制映射!