C# .Net實現灰度圖和HeatMap熱力圖winform(進階)
一、前文
前文可以參考我的前一篇博文:C# .Net實現簡易灰度圖和酷炫HeatMap熱力圖winform
但是,先前的熱力圖效果,我並不滿意。不滿意的地方主要有三點:
- 熱力圖的顏色是通過一個調色板圖片來實現,如果想要其他顏色,改起來比較麻煩
- 熱力圖的擴散效果不好看,不夠漸進
- 熱力圖的每個點大小都一致,應該是大小不一才對
因此,我做瞭改進,上一個圖是之前的效果,下一個圖是改進後的效果
二、漸進顏色調色板
//創建調色板,顏色映射 private ColorMap[] CreatePalette() { ColorMap[] colorMaps = new ColorMap[256]; List<Color> newColors = new List<Color>(); //顏色集合 newColors.AddRange(GetGradientColorList(Color.Red, Color.Yellow, 64)); newColors.AddRange(GetGradientColorList(Color.Yellow, Color.Green, 64)); newColors.AddRange(GetGradientColorList(Color.Green, Color.Blue, 64)); newColors.AddRange(GetGradientColorList(Color.Blue, Color.Navy, 64)); //顏色調色板展示 Bitmap colorBitmap = new Bitmap(colorPanel.Width, colorPanel.Height); Graphics graphic = Graphics.FromImage(colorBitmap); for (int i = 0; i < 256; i++) { SolidBrush solidBrush = new SolidBrush(newColors[i]); Rectangle rectangle = new Rectangle((int)(i * 2), 0, (int)2, colorPanel.Height); graphic.FillRectangle(solidBrush, rectangle); graphic.Save(); solidBrush.Dispose(); } colorPanel.BackgroundImage = colorBitmap; // 遍歷每個像素並創建一個新的顏色映射 for (int X = 0; X <= 255; X++) { colorMaps[X] = new ColorMap(); colorMaps[X].OldColor = System.Drawing.Color.FromArgb(X, X, X); colorMaps[X].NewColor = System.Drawing.Color.FromArgb(255, newColors[X]); } return colorMaps; } /// <summary> /// 獲得兩個顏色之間漸進顏色的集合 /// </summary> /// <param name="sourceColor">起始顏色</param> /// <param name="destColor">終止顏色</param> /// <param name="count">漸進顏色的個數</param> /// <returns>返回顏色集合</returns> public static List<Color> GetGradientColorList(Color srcColor, Color desColor, int count) { List<Color> colorFactorList = new List<Color>(); int redSpan = desColor.R - srcColor.R; int greenSpan = desColor.G - srcColor.G; int blueSpan = desColor.B - srcColor.B; for (int i = 0; i < count; i++) { Color color = Color.FromArgb( srcColor.R + (int)((double)i / count * redSpan), srcColor.G + (int)((double)i / count * greenSpan), srcColor.B + (int)((double)i / count * blueSpan) ); colorFactorList.Add(color); } return colorFactorList; }
三、熱力點大小和擴展大小
private void DrawHeatPoint2(Graphics graphics, HeatPoint heatPoint) { Console.WriteLine("heatPoint.Intensity = " + heatPoint.Intensity); int radius = 40 * (heatPoint.Intensity+6) / 240; List<System.Drawing.Point> pointsList = new List<System.Drawing.Point>(); for (double degrees = 0; degrees <= 360; degrees += 10) { // 在定義半徑的圓的圓周上繪制新點 // 使用點坐標、半徑和角度 // 計算這個迭代點在圓上的位置 System.Drawing.Point point = new System.Drawing.Point(); point.X = Convert.ToInt32(heatPoint.X + radius * Math.Cos((Math.PI / 180) * degrees)); point.Y = Convert.ToInt32(heatPoint.Y + radius * Math.Sin((Math.PI / 180) * degrees)); pointsList.Add(point); } // 創建新的顏色混合來告訴 PathGradientBrush 使用什麼顏色以及放置它們的位置 ColorBlend colorBlend = new ColorBlend(3); colorBlend.Positions = new float[3] { 0, 0.8f, 1 }; colorBlend.Colors = new System.Drawing.Color[3] { System.Drawing.Color.FromArgb(0, System.Drawing.Color.White), System.Drawing.Color.FromArgb(heatPoint.Intensity, System.Drawing.Color.Black), System.Drawing.Color.FromArgb(heatPoint.Intensity, System.Drawing.Color.Black) }; // 創建新的 PathGradientBrush 以使用圓周點創建徑向漸變 PathGradientBrush brush = new PathGradientBrush(pointsList.ToArray()); // 將顏色混合傳遞給 PathGradientBrush 以指示它如何生成漸變 brush.InterpolationColors = colorBlend; graphics.FillPolygon(brush, pointsList.ToArray()); //brush.Dispose(); }
四、更新視圖
private void UpdateView()
{
//灰度
Bitmap bitmap1 = CreateIntensityMask(new Bitmap((int)panel1.Width, (int)panel1.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb), heatPoints, 1);
panel1.BackgroundImage = bitmap1;
//上色
panel3.BackgroundImage = Colorize(bitmap1);
}
private Bitmap CreateIntensityMask(Bitmap bitmap, List<HeatPoint> aHeatPoints)
{
//從Bitmap獲得Graphics GDI+ 繪圖圖面
Graphics graphics = Graphics.FromImage(bitmap);
//清除整個繪圖面並以白色填充
graphics.Clear(System.Drawing.Color.White);
foreach (HeatPoint point in aHeatPoints)
{
DrawHeatPoint2(graphics, point);
}
return bitmap;
}
到此這篇關於C# .Net實現灰度圖和HeatMap熱力圖winform(進階)的文章就介紹到這瞭,更多相關C# .Net 灰度圖 熱力圖內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!