2017-01-13 164 views
1

我需要將24位顏色轉換爲4位RGBI(1位用於紅色,綠色,藍色+亮度)。將24位顏色轉換爲4位RGBI

轉換爲3位RGB相當簡單:如果大於127則設置顏色位,否則清除。但是,所有三個通道只有一個強度位,那麼設置它的正確方法是什麼(如果有的話)?

首先我考慮分割的8位信道到三個部分象下面這樣:

  • 如果0 < =顏色< = 85,然後清除RGBI色位
  • 如果86 < =顏色< = 170,然後設置RGBI色位
  • 如果171 < =顏色< = 255,然後設置RGBI色位和強度

但是後來我認爲只有在三個通道中的兩個通道大於127時,正確的方法纔是設置強度位。但是在這種情況下,純R,G或B不會有強度設置(例如,在RBG的情況下(0,0,200)

任何意見是高度讚賞

+0

你只是想將每個24位顏色轉換爲最接近的4位顏色,或者你是否真的想要做一些顏色抖動? –

+0

@IlmariKaronen到最接近的等值 –

回答

1

一種簡單的方法找到最接近的近似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