Skip to content

Commit c2f717b

Browse files
committed
添加颜色模式转换
1 parent a2d7667 commit c2f717b

2 files changed

Lines changed: 210 additions & 0 deletions

File tree

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using DotNetCampus.MediaConverters.Imaging.Effect.Extensions;
7+
8+
namespace DotNetCampus.MediaConverters.Imaging.Effect.Color;
9+
10+
/// <summary>
11+
/// 色彩模式转换器
12+
/// </summary>
13+
public static class ColorModeConverter
14+
{
15+
/// <summary>
16+
/// RGB转HSL(参数值取值范围为0-1)
17+
/// 注:Windows使用的色彩模式是HSL
18+
/// </summary>
19+
/// <param name="r">红色[范围0-1]</param>
20+
/// <param name="g">绿色[范围0-1]</param>
21+
/// <param name="b">蓝色[范围0-1]</param>
22+
/// <returns> 色相[范围0-1], 饱和度[范围0-1], 明度[范围0-1]</returns>
23+
public static (float hue, float saturation, float brightness) RgbToHsl(float r, float g, float b)
24+
{
25+
var max = Math.Max(Math.Max(r, g), b);
26+
var min = Math.Min(Math.Min(r, g), b);
27+
28+
//计算色相
29+
float hue;
30+
var delta = max - min;
31+
if (r.AlmostEquals(max))
32+
hue = (g - b) / delta;
33+
else if (g.AlmostEquals(max))
34+
hue = (b - r) / delta + 2f;
35+
else
36+
hue = (r - g) / delta + 4f;
37+
hue *= 60f;
38+
if (hue < 0f)
39+
hue += 360f;
40+
41+
//计算饱和度
42+
var saturation = 0f;
43+
if (!r.AlmostEquals(g) || b.AlmostEquals(g))
44+
{
45+
var div = max + min;
46+
if (div > 1f)
47+
div = 1f * 2 - max - min;
48+
saturation = (max - min) / div;
49+
}
50+
51+
//计算明度
52+
var brightness = (max + min) / 2;
53+
54+
//值归一化
55+
return (hue / 360f, saturation, brightness);
56+
}
57+
58+
/// <summary>
59+
/// HSL转RBG(参数值取值范围为0-1)
60+
/// 注:Windows使用的色彩模式是HSL
61+
/// </summary>
62+
/// <param name="hue">色相[范围0-1]</param>
63+
/// <param name="saturation">饱和度[范围0-1]</param>
64+
/// <param name="lightness">明度[范围0-1]</param>
65+
/// <returns>红色[范围0-1], 绿色[范围0-1], 蓝色[范围0-1]</returns>
66+
public static (float, float, float) HslToRgb(float hue, float saturation, float lightness)
67+
{
68+
if (saturation == 0)
69+
{
70+
return (lightness, lightness, lightness);
71+
}
72+
else
73+
{
74+
var q = lightness < 0.5
75+
? lightness * (1 + saturation)
76+
: lightness + saturation - lightness * saturation;
77+
var p = 2 * lightness - q;
78+
var rgb = new[] { hue + 1 / 3f, hue, hue - 1 / 3f };
79+
for (var i = 0; i < 3; i++)
80+
{
81+
if (rgb[i] < 0)
82+
rgb[i] += 1;
83+
if (rgb[i] > 1)
84+
rgb[i] -= 1;
85+
if (rgb[i] * 6 < 1)
86+
{
87+
rgb[i] = p + (q - p) * 6 * rgb[i];
88+
}
89+
else if (rgb[i] * 2 < 1)
90+
{
91+
rgb[i] = q;
92+
}
93+
else if (rgb[i] * 3 < 2)
94+
{
95+
rgb[i] = p + (q - p) * (2 / 3f - rgb[i]) * 6;
96+
}
97+
else
98+
rgb[i] = p;
99+
}
100+
101+
return (rgb[0], rgb[1], rgb[2]);
102+
}
103+
}
104+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics.CodeAnalysis;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace DotNetCampus.MediaConverters.Imaging.Effect.Extensions;
9+
10+
/// <summary>
11+
/// 数学拓展方法
12+
/// </summary>
13+
[SuppressMessage("ReSharper", "CompareOfFloatsByEqualityOperator")]
14+
internal static class MathExtension
15+
{
16+
/// <summary>
17+
/// 比较两个double值的大小
18+
/// </summary>
19+
/// <param name="a"></param>
20+
/// <param name="b"></param>
21+
/// <param name="epsilon"></param>
22+
/// <returns></returns>
23+
public static bool AlmostEquals(this double a, double b, double epsilon = 0.00001)
24+
{
25+
if (double.IsNaN(a) || double.IsNaN(b))
26+
{
27+
return false;
28+
}
29+
30+
if (double.IsPositiveInfinity(a) || double.IsPositiveInfinity(b))
31+
{
32+
return a == b;
33+
}
34+
35+
if (double.IsNegativeInfinity(a) || double.IsNegativeInfinity(b))
36+
{
37+
return a == b;
38+
}
39+
40+
return Math.Abs(a - b) < epsilon;
41+
}
42+
43+
44+
/// <summary>
45+
/// 比较两个float值的大小
46+
/// </summary>
47+
/// <param name="a"></param>
48+
/// <param name="b"></param>
49+
/// <param name="epsilon"></param>
50+
/// <returns></returns>
51+
public static bool AlmostEquals(this float a, float b, float epsilon = 0.00001f)
52+
{
53+
if (float.IsNaN(a) || float.IsNaN(b))
54+
{
55+
return false;
56+
}
57+
58+
if (float.IsPositiveInfinity(a) || float.IsPositiveInfinity(b))
59+
{
60+
return a == b;
61+
}
62+
63+
if (float.IsNegativeInfinity(a) || float.IsNegativeInfinity(b))
64+
{
65+
return a == b;
66+
}
67+
68+
return Math.Abs(a - b) < epsilon;
69+
}
70+
71+
/// <summary>
72+
/// 矩阵乘法
73+
/// </summary>
74+
/// <param name="a"></param>
75+
/// <param name="b"></param>
76+
/// <returns></returns>
77+
/// <exception cref="Exception"></exception>
78+
public static float[,] MultiplyMatrices(float[,] a, float[,] b)
79+
{
80+
var aRows = a.GetLength(0);
81+
var aCols = a.GetLength(1);
82+
var bRows = b.GetLength(0);
83+
var bCols = b.GetLength(1);
84+
85+
if (aCols != bRows)
86+
throw new Exception("Inner matrix dimensions must match.");
87+
88+
var result = new float[aRows, bCols];
89+
90+
for (var i = 0; i < aRows; ++i)
91+
{
92+
for (var j = 0; j < bCols; ++j)
93+
{
94+
float sum = 0;
95+
for (var k = 0; k < aCols; ++k)
96+
{
97+
sum += (a[i, k] * b[k, j]);
98+
}
99+
result[i, j] = sum;
100+
}
101+
}
102+
103+
return result;
104+
}
105+
106+
}

0 commit comments

Comments
 (0)