我需要手动将rgba8转换为rgba5551。我从另一篇文章中找到了一些有用的代码,并希望将其修改为从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 :(得分:0)
RGBA5551的值是它将颜色信息压缩为16位 - 或两个字节,alpha通道只有一位(开或关)。另一方面,RGBA8888对每个通道使用一个字节。 (如果你不需要alpha通道,我听说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;
}
您当然可以压缩此代码。