2013-05-24 5 views
0

Мне нужно преобразовать rgba8 в rgba5551 вручную. Я нашел полезный код из другого сообщения и хочу его модифицировать для преобразования из rgba8 в rgba5551. У меня нет опыта работы с bitewise, и мне не повезло с кодом.Вручную Преобразование rgba8 в rgba5551

void* rgba8888_to_rgba4444(void* src, int src_bytes) 
{ 
    // compute the actual number of pixel elements in the buffer. 
    int num_pixels = src_bytes/4; 
    unsigned long* psrc = (unsigned long*)src; 
    unsigned short* pdst = (unsigned short*)src; 
    // convert every pixel 
    for(int i = 0; i < num_pixels; i++){ 
     // read a source pixel 
     unsigned px = psrc[i]; 
     // unpack the source data as 8 bit values 
     unsigned r = (px << 8) & 0xf000; 
     unsigned g = (px >> 4) & 0x0f00; 
     unsigned b = (px >> 16) & 0x00f0; 
     unsigned a = (px >> 28) & 0x000f; 
     // and store 
     pdst[i] = r | g | b | a; 
    } 
    return pdst; 
} 

ответ

0

Значение RGBA5551 является то, что она имеет цветовую информацию конденсируется на 16 бит - или два байта, только с одним битом для альфа-канала (включено или выключено). С другой стороны, RGBA8888 использует байты для каждого канала. (Если вам не нужен альфа-канал, я лучше слышу RGB565 - так как люди более чувствительны к зеленому). Теперь, с 5 битами, вы получаете числа от 0 до 31, поэтому r, g и b каждый должен быть преобразован в некоторое число от 0 до 31, и поскольку они изначально байта каждый (0-255), умножим каждый на 31/255. Вот функция, которая принимает RGBA байт в качестве входных данных и выводит RGBA5551 как короткий:

short int RGBA8888_to_RGBA5551(unsigned char r, unsigned char g, unsigned char b, unsigned char a){ 
    unsigned char r5 = r*31/255; // All arithmetic is integer arithmetic, and so floating points are truncated. If you want to round to the nearest integer, adjust this code accordingly. 
    unsigned char g5 = g*31/255; 
    unsigned char b5 = b*31/255; 
    unsigned char a1 = (a > 0) ? 1 : 0; // 1 if a is positive, 0 else. You must decide what is sensible. 

    // Now that we have our 5 bit r, g, and b and our 1 bit a, we need to shift them into place before combining. 

    short int rShift = (short int)r5 << 11; // (short int)r5 looks like 00000000000vwxyz - 11 zeroes. I'm not sure if you need (short int), but I've wasted time tracking down bugs where I didn't typecast properly before shifting. 
    short int gShift = (short int)g5 << 6; 
    short int bShift = (short int)b5 << 1; 

    // Combine and return 
    return rShift | gShift | bShift | a1; 
} 

Вы можете, конечно, конденсируется этот код.