C#色彩空间转换算法需求:基于RYB实现多格式互转
基于RYB的多色彩空间转换实现
已验证的RYB与RGB双向转换代码
RYB转RGB
public static int[] ryb2rgb(int[] cveta) { double w; double r; double y; double b; double g; double myc; double mgc; w = Math.Min(Math.Min(cveta[0], cveta[1]), cveta[2]); r = (double)(cveta[0]) - w; y = (double)(cveta[1]) - w; b = (double)(cveta[2]) - w; myc = Math.Max(Math.Max(r, y), b); g = Math.Min(y, b); y -= g; b -= g; b *= 2.0; g *= 2.0; r += y; g += y; mgc = Math.Max(Math.Max(r, g), b); if (mgc != 0) { r *= (myc / mgc); g *= (myc / mgc); b *= (myc / mgc); } r += w; g += w; b += w; return new int[3] {(int)r, (int)g, (int)b}; }
RGB转RYB
public static int[] rgb2ryb(int[] cveta) { double w; double r; double g; double b; double y; double mgc; double myc; w = Math.Min(Math.Min(cveta[0], cveta[1]), cveta[2]); r = (double)(cveta[0]) - w; g = (double)(cveta[1]) - w; b = (double)(cveta[2]) - w; mgc = Math.Max(Math.Max(r, g), b); y = Math.Min(r, g); r -= y; g -= y; b /= 2.0; g /= 2.0; y += g; b += g; myc = Math.Max(Math.Max(r, g), b); if (myc != 0) { r *= (mgc / myc); y *= (mgc / myc); b *= (mgc / myc); } r += w; y += w; b += w; return new int[3] {(int)r, (int)y, (int)b}; }
RYB与其他色彩空间的转换方案
所有转换均通过RYB↔RGB作为中间层实现,以下是各色彩空间与RGB的双向转换代码(无内置方法、无十六进制依赖):
1. RGB ↔ RGBA
RGBA在RGB基础上增加Alpha通道(取值范围0-255,0为全透明,255为完全不透明):
RGB转RGBA
// alpha为指定的透明度值(0-255) public static int[] rgb2rgba(int[] rgb, int alpha) { return new int[4] { rgb[0], rgb[1], rgb[2], alpha }; }
RGBA转RGB
public static int[] rgba2rgb(int[] rgba) { // 忽略Alpha通道,直接返回RGB分量 return new int[3] { rgba[0], rgba[1], rgba[2] }; }
基于RYB的RGBA转换
- RYB转RGBA:
rgb2rgba(ryb2rgb(ryb), alpha) - RGBA转RYB:
rgb2ryb(rgba2rgb(rgba))
2. RGB ↔ HSL
HSL分量定义:H(色相,0-360)、S(饱和度,0-100)、L(亮度,0-100)
RGB转HSL
public static double[] rgb2hsl(int[] rgb) { double r = rgb[0] / 255.0; double g = rgb[1] / 255.0; double b = rgb[2] / 255.0; double max = Math.Max(Math.Max(r, g), b); double min = Math.Min(Math.Min(r, g), b); double h, s, l = (max + min) / 2; if (max == min) { h = 0; s = 0; } else { double d = max - min; s = l > 0.5 ? d / (2 - max - min) : d / (max + min); if (max == r) h = (g - b) / d + (g < b ? 6 : 0); else if (max == g) h = (b - r) / d + 2; else h = (r - g) / d + 4; h *= 60; } // 转换为整数范围:H(0-360), S(0-100), L(0-100) return new double[] { Math.Round(h), Math.Round(s * 100), Math.Round(l * 100) }; }
HSL转RGB
public static int[] hsl2rgb(double[] hsl) { double h = hsl[0] / 360.0; double s = hsl[1] / 100.0; double l = hsl[2] / 100.0; double r, g, b; if (s == 0) { r = g = b = l; } else { double q = l < 0.5 ? l * (1 + s) : l + s - l * s; double p = 2 * l - q; r = HueToRgb(p, q, h + 1.0/3); g = HueToRgb(p, q, h); b = HueToRgb(p, q, h - 1.0/3); } return new int[] { (int)Math.Round(r * 255), (int)Math.Round(g * 255), (int)Math.Round(b * 255) }; } // 辅助函数:色相转RGB分量 private static double HueToRgb(double p, double q, double t) { if (t < 0) t += 1; if (t > 1) t -= 1; if (t < 1.0/6) return p + (q - p) * 6 * t; if (t < 1.0/2) return q; if (t < 2.0/3) return p + (q - p) * (2.0/3 - t) * 6; return p; }
基于RYB的HSL转换
- RYB转HSL:
rgb2hsl(ryb2rgb(ryb)) - HSL转RYB:
rgb2ryb(hsl2rgb(hsl))
3. RGB ↔ HSV
HSV分量定义:H(色相,0-360)、S(饱和度,0-100)、V(明度,0-100)
RGB转HSV
public static double[] rgb2hsv(int[] rgb) { double r = rgb[0] / 255.0; double g = rgb[1] / 255.0; double b = rgb[2] / 255.0; double max = Math.Max(Math.Max(r, g), b); double min = Math.Min(Math.Min(r, g), b); double h, s, v = max; double d = max - min; s = max == 0 ? 0 : d / max; if (max == min) { h = 0; } else { if (max == r) h = (g - b) / d + (g < b ? 6 : 0); else if (max == g) h = (b - r) / d + 2; else h = (r - g) / d + 4; h *= 60; } // 转换为整数范围:H(0-360), S(0-100), V(0-100) return new double[] { Math.Round(h), Math.Round(s * 100), Math.Round(v * 100) }; }
HSV转RGB
public static int[] hsv2rgb(double[] hsv) { double h = hsv[0] / 360.0; double s = hsv[1] / 100.0; double v = hsv[2] / 100.0; int i = (int)Math.Floor(h * 6); double f = h * 6 - i; double p = v * (1 - s); double q = v * (1 - f * s); double t = v * (1 - (1 - f) * s); double r, g, b; switch (i % 6) { case 0: r = v; g = t; b = p; break; case 1: r = q; g = v; b = p; break; case 2: r = p; g = v; b = t; break; case 3: r = p; g = q; b = v; break; case 4: r = t; g = p; b = v; break; default: r = v; g = p; b = q; break; } return new int[] { (int)Math.Round(r * 255), (int)Math.Round(g * 255), (int)Math.Round(b * 255) }; }
基于RYB的HSV转换
- RYB转HSV:
rgb2hsv(ryb2rgb(ryb)) - HSV转RYB:
rgb2ryb(hsv2rgb(hsv))
4. RGB ↔ CMY
CMY为RGB的互补色,分量取值范围0-255:
RGB转CMY
public static int[] rgb2cmy(int[] rgb) { return new int[] { 255 - rgb[0], 255 - rgb[1], 255 - rgb[2] }; }
CMY转RGB
public static int[] cmy2rgb(int[] cmy) { return new int[] { 255 - cmy[0], 255 - cmy[1], 255 - cmy[2] }; }
基于RYB的CMY转换
- RYB转CMY:
rgb2cmy(ryb2rgb(ryb)) - CMY转RYB:
rgb2ryb(cmy2rgb(cmy))
5. RGB ↔ CMYK
CMYK分量定义:C(青)、M(品红)、Y(黄)、K(黑),取值范围0-100(百分比)
RGB转CMYK
public static double[] rgb2cmyk(int[] rgb) { double r = rgb[0] / 255.0; double g = rgb[1] / 255.0; double b = rgb[2] / 255.0; double k = 1 - Math.Max(Math.Max(r, g), b); double c, m, y; if (k == 1) { c = m = y = 0; } else { c = (1 - r - k) / (1 - k); m = (1 - g - k) / (1 - k); y = (1 - b - k) / (1 - k); } // 转换为百分比范围(0-100) return new double[] { Math.Round(c * 100), Math.Round(m * 100), Math.Round(y * 100), Math.Round(k * 100) }; }
CMYK转RGB
public static int[] cmyk2rgb(double[] cmyk) { double c = cmyk[0] / 100.0; double m = cmyk[1] / 100.0; double y = cmyk[2] / 100.0; double k = cmyk[3] / 100.0; double r = (1 - c) * (1 - k); double g = (1 - m) * (1 - k); double b = (1 - y) * (1 - k); return new int[] { (int)Math.Round(r * 255), (int)Math.Round(g * 255), (int)Math.Round(b * 255) }; }
基于RYB的CMYK转换
- RYB转CMYK:
rgb2cmyk(ryb2rgb(ryb)) - CMYK转RYB:
rgb2ryb(cmyk2rgb(cmyk))
内容的提问来源于stack exchange,提问作者Red Mermaid
相关产品推荐
相关产品推荐

