将24位颜色转换为4位RGBI

时间:2017-01-13 23:00:48

标签: colors

我需要将24位颜色转换为4位RGBI(红色,绿色,蓝色+强度为1位)。

转换为3位RGB非常简单:如果大于127,则设置颜色位,否则清除。但是,所有三个通道只有一个强度位,那么设置它的正确方法是什么(如果有的话)?

首先,我考虑将8位通道分为以下三个部分:

  • 如果0 <= color&lt; = 85,则清除rgbi-color bit
  • 如果86&lt; = color&lt; = 170,则设置rgbi-color bit
  • 如果171&lt; = color&lt; = 255,则设置rgbi-color位和强度

但后来我认为,只有当三个通道中的两个大于127时,正确的方法才是设置强度位。但在这种情况下,纯R,G或B将不会设置强度(例如,如果是rbg(0,0,200)

非常感谢任何建议

1 个答案:

答案 0 :(得分:2)

找到最接近的4-bit RGBI近似颜色的一种简单方法是分别考虑强度位的两种可能性。也就是说,首先找到颜色最接近的RGB0和RGB1近似值(这很容易做到,只需将每个颜色轴分割到适当的点),然后确定哪些近似值更好。

这是该算法的一个简单的C-ish伪代码描述:

// find the closest RGBx approximation of a 24-bit RGB color, for x = 0 or 1
function rgbx_approx(red, green, blue, x) {
    threshold = (x + 1) * 255 / 3;
    r = (red > threshold ? 1 : 0);
    g = (green > threshold ? 1 : 0);
    b = (blue > threshold ? 1 : 0);
    return (r, g, b);
}

// convert a 4-bit RGBI color back to 24-bit RGB
function rgbi_to_rgb24(r, g, b, i) {
   red = (2*r + i) * 255 / 3;
   green = (2*g + i) * 255 / 3;
   blue = (2*b + i) * 255 / 3;
   return (red, green, blue);
}

// return the (squared) Euclidean distance between two RGB colors
function color_distance(red_a, green_a, blue_a, red_b, green_b, blue_b) {
   d_red = red_a - red_b;
   d_green = green_a - green_b;
   d_blue = blue_a - blue_b;
   return (d_red * d_red) + (d_green * d_green) + (d_blue * d_blue);
}

// find the closest 4-bit RGBI approximation (by Euclidean distance) to a 24-bit RGB color
function rgbi_approx(red, green, blue) {
    // find best RGB0 and RGB1 approximations:
    (r0, g0, b0) = rgbx_approx(red, green, blue, 0);
    (r1, g1, b1) = rgbx_approx(red, green, blue, 1);

    // convert them back to 24-bit RGB:
    (red0, green0, blue0) = rgbi_to_rgb24(r0, g0, b0, 0);
    (red1, green1, blue1) = rgbi_to_rgb24(r1, g1, b1, 1);

    // return the color closer to the original:
    d0 = color_distance(red, green, blue, red0, green0, blue0);
    d1 = color_distance(red, green, blue, red1, green1, blue1);

    if (d0 <= d1) return (r0, g0, b0, 0);
    else return (r1, g1, b1, 1);
}

或者,您可以简单地使用任何通用的固定调色板颜色量化算法。如果您的实际调色板不是像上面代码所假设的那样纯粹均匀间隔的RGBI调色板,那么这可能会产生更好的结果,而是像CGA tweaked RGBI palette