最近做tchart曲线显示的时候,因为曲线太多,导致tchart到后面的曲线颜色一样,所以打算自己给曲线设置颜色。最后选用的是色阶文件生成常用的渐变色,例子如下所示:
ps:色阶文件及完整代码地址:
https://download.youkuaiyun.com/download/Yyuanyuxin/12858219
色阶文件的读取:
色阶文件也可以自己编写。
内容如下:
如上:蓝色划出的是专用连接(暂时用不上),红色划出的是位置,黄色为颜色,即百分比(例如44表示在44%的位置为rgb为102,51,0的颜色,最后一位是透明度,暂时用不上)。
下面是读取及解析所有的色阶文件,GradientColorClass
是我自己定义保存色阶文件的类,可自己定义。
public static List<GradientColorClass> GetAllColorFile(string dir)
{
List<GradientColorClass> colorClass = new List<GradientColorClass>();
DirectoryInfo root = new DirectoryInfo(dir);
foreach (var item in root.GetFiles())
{
//读取文件
GradientColorClass gradientColor = new GradientColorClass();
string info = File.ReadAllText(item.FullName);
var list = info.Replace("\r\n", ",").Replace("\r", ",").Trim().Split(',');
if (list.Length <= 1) continue;
List<float> colorPositions = new List<float>();
List<Color> colorList = new List<Color>();
foreach (var color in list)
{
var colorInfo = color.Trim();
if (string.IsNullOrEmpty(color)) continue;
var arr = colorInfo.Split(' ');
var dealArr = new List<string>();
//解决中间空格个数不确定
foreach (var text in arr)
{
var dealText = text.Trim();
if (!string.IsNullOrEmpty(dealText))
{
dealArr.Add(dealText);
}
}
if (dealArr.Count < 4) continue;
if (float.TryParse(dealArr[0], out float position) && int.TryParse(dealArr[1], out int r) && int.TryParse(dealArr[2], out int g) && int.TryParse(dealArr[3], out int b))
{
colorList.Add(Color.FromArgb(r, g, b));
colorPositions.Add(position / 100);
}
}
gradientColor.FileName = item.Name;
gradientColor.ColorList = colorList.ToArray();
gradientColor.ColorPositions = colorPositions.ToArray();
gradientColor.Text = info;
gradientColor.FullPath = item.FullName;
colorClass.Add(gradientColor);
}
return colorClass;
}
绘制渐变图片(方法1:绘制已有控件上)
上面得到色阶解析颜色之后,就可以绘制了
绘制函数如下:
public static void DrawColorPolygon(Graphics g, Color[] colorList, float[] colorPositions, int width = 100, int heigh = 50)
{
try
{
//绘画一个四边形
//PointF[] _pointfs = new PointF[4];
//_pointfs[0] = new PointF(100, 50);
//_pointfs[1] = new PointF(50, 80);
//_pointfs[2] = new PointF(200, 80);
//_pointfs[3] = new PointF(150, 50);
//g.DrawPolygon(Pens.Black, _pointfs);
//绘制矩形
RectangleF _pointfs = new RectangleF(0, 0, width, heigh);
g.DrawRectangle(Pens.Black, 0, 0, width, heigh);
//设置Rectangle
Rectangle _rect = new Rectangle(0, 0, width, heigh);
LinearGradientBrush _linearGradientBrush = new LinearGradientBrush(
_rect, Color.Red, Color.White, LinearGradientMode.Horizontal);
//定义用于在多色渐变中以内插值取代颜色混合的颜色和位置的数组
ColorBlend _colorBlend = new ColorBlend();
//定义多种颜色
_colorBlend.Colors = colorList;
_colorBlend.Positions = colorPositions;// new float[] { 0/2f,3 / 4f, 2 / 2f};
//设置多色渐变颜色
_linearGradientBrush.InterpolationColors = _colorBlend;
//填充多边形
g.FillRectangle(_linearGradientBrush, _pointfs);
//g.DrawString("sss", new Font("宋体", 12, FontStyle.Bold), new SolidBrush(Color.Black), 1, 1);
_linearGradientBrush.Dispose();
}
catch (Exception ex)
{
throw;
}
}
使用:
或者一般在paint事件
public void Show(GradientColorClass colorClass)
{
Graphics g = this.Graphics;//需要绘制的控件画布
DrawColorPolygon(g, colorClass.ColorList, colorClass.ColorPositions);
}
绘制渐变图片(方法二:生成image图片)
public static Bitmap DrawColorPolygon(Color[] colorList, float[] colorPositions, int width = 100, int heigh = 50)
{
try
{
Bitmap flag = new Bitmap(width, heigh);
Graphics g = Graphics.FromImage(flag);
DrawColorPolygon(g, colorList, colorPositions, width, heigh);
return flag;
}
catch (Exception ex)
{
return null;
}
}
使用:
var img = DrawColorPolygon(selectedColor.ColorList, selectedColor.ColorPositions, width, heigh);
pb_color.Image = img;
从色阶中取色
/// <summary>
/// 拆分色阶,得到颜色列表(按RGB的百分百拆分)
/// </summary>
/// <param name="colors">色阶类</param>
/// <param name="count">需要得到的颜色数量,因为有小数会加1化整,一般会得到更多的颜色数量</param>
/// <returns></returns>
public static List<Color> GetCheckColor(GradientColorClass colors, int count)
{
if (colors == null|| count==0) return null;
List<Color> selectedColor = new List<Color>();
for (int j = 0; j < colors.ColorPositions.Length - 1; j++)
{
var max = colors.ColorPositions[j + 1];
var min = colors.ColorPositions[j];
var color1 = colors.ColorList[j];
var color2 = colors.ColorList[j + 1];
var colorCount = Math.Ceiling(count * (max - min));//每一个色块里面有多少个颜色
for (int i = 0; i < colorCount; i++)
{
if (i == 0)
{
selectedColor.Add(color1);
}
else
{
var r = (int)(Math.Abs(color2.R - color1.R) * (i / colorCount));
var g = (int)(Math.Abs(color2.G - color1.G) * (i / colorCount));
var b = (int)(Math.Abs(color2.B - color1.B) * (i / colorCount));
selectedColor.Add(Color.FromArgb(r, g, b));
}
}
}
return selectedColor;
}
/// <summary>
/// 拆分色阶,得到颜色列表(取图片像素点)
/// </summary>
/// <param name="colors">色阶类</param>
/// <param name="count">需要得到的颜色数量,因为有小数会加1化整,一般会得到更多的颜色数量</param>
/// <returns></returns>
public static List<Color> GetCheckColor(Bitmap colors, int count)
{
if (colors == null || count <= 0) return null;
List<Color> selectedColor = new List<Color>();
var addCount = colors.Width / count;
for (int j = 0; j < count; j++)
{
selectedColor.Add(colors.GetPixel(j * addCount, 1));
}
return selectedColor;
}