最近在研究图像颜色格式,需要用到图像颜色格式转换,记录在此。
由大转小
例如:RGB888转RGB565
需要量化压缩将8位数据压缩成5位和6位;压缩规则:取高位,例如:8位转5位,取高5位,再将获取到的RGB数据,按照RGB565的顺序排列好。
量化上做了压缩,却损失了精度。
由小转大
例如:RGB565转RGB888
需要量化补偿;补偿规则:将原数据填充至高位,对于低位,用原始数据的低位进行补偿,如果仍然有未填充的位,继续使用原始数据的低位进行循环补偿。
#include <stdio.h>
#include <stdint.h>
unsigned int Rgb888toArgb8888(unsigned int rgb24, int a)
{
if(a <= 0)
return 0;
return (a << 24) + rgb24;
}
unsigned int argb1555_to_argbB8888(unsigned short c)
{
const unsigned int a = c&0x8000, r = c&0x7C00, g = c&0x03E0, b = c&0x1F;
const unsigned int rgb = (r << 9) | (g << 6) | (b << 3);
return (a*0x1FE00) | rgb | ((rgb >> 5) & 0x070707);
}
unsigned short argb8888_to_argb1555(unsigned int color)
{
unsigned int a = (((color&0xff000000)>>24) +127)/255;
unsigned int r = (((color&0x00ff0000)>>16)*31 +127)/255;
unsigned int g = (((color&0x0000ff00)>>8)*31 +127)/255;
unsigned int b = (((color&0x000000ff))*31 +127)/255;
unsigned short argb1555 = (a << 15) | (r << 10) | (g << 5) | b;
return argb1555;
}
int main(int argc, char *argv[])
{
unsigned int rgb32 = Rgb888toArgb8888(0x92d050, 0xff);
printf("rgb32:%x\n", rgb32);
unsigned short argb1555 = argb8888_to_argb1555(rgb32);
printf("argb1555:%x\n", argb1555);
unsigned int color = argb1555_to_argbB8888(argb1555);
printf("argb8888:%x\n", color);
return 0;
}
需要知道的是,从大到小转换会丢失精度,颜色压缩后,跟原来的色彩是有差异的!我这边试着会比原来的色彩偏淡。