RGB888->RGB565

今天在RGB888到RGB565的转换的时候迷茫了一天,查阅相关资料,看了好多转换代码,经过不懈努力到了最后算是搞明白了,特分享一下:

先说一下量化压缩与量化补偿:

在进行色彩格式转换的时候,经常会遇到色彩量化位数的改变,比如说从 24bit RGB888 到 16bit RGB565 的色彩转换。所谓量化压缩与量化补偿网上人士相关提出的概念,不知道是否准确,不过能很好的说明问题,现说明如下:

  量化压缩,举例:

  24bit RGB888 -> 16bit RGB565 的转换

  24ibt RGB888 R7 R6 R5 R4 R3 R2 R1 R0 G7 G6 G5 G4 G3 G2 G1 G0 B7 B6 B5 B4 B3 B2 B1 B0

  16bit RGB656 R7 R6 R5 R4 R3 G7 G6 G5 G4 G3 G2 B7 B6 B5 B4 B3

  量化位数从8bit到5bit或6bit,取原8bit的高位,量化上做了压缩,却损失了精度。

  量化补偿,举例:

  16bit RGB565 -> 24bit RGB888 的转换

  16bit RGB656 R4 R3 R2 R1 R0 G5 G4 G3 G2 G1 G0 B4 B3 B2 B1 B0

  24ibt RGB888 R4 R3 R2 R1 R0 0 0 0 G5 G4 G3 G2 G1 G0 0 0 B4 B3 B2 B1 B0 0 0 0

  24ibt RGB888 R4 R3 R2 R1 R0 R2 R1 R0 G5 G4 G3 G2 G1 G0 G1 G0 B4 B3 B2 B1 B0 B2 B1 B0

  说明:第二行的 24bit RGB888 数据为转换后,未进行补偿的数据,在精度上会有损失

  第三行的 24bit RGB888 数据为经过量化补偿的数据,对低位做了量化补偿

  可以很容易的证明,这样的补偿方法是一种合理的线性补偿。补偿的原理很简单,大家仔细想一下就明白了,因此不再详细说明。

  总结一下:

  量化压缩的方法:三个字取高位

  量化补偿的方法:

  1. 将原数据填充至高位

  2. 对于低位,用原始数据的低位进行补偿

  3. 如果仍然有未填充的位,继续使用原始数据的低位进行循环补偿

  解释一下循环补偿的概念:

  8bit RGB332 -> 24bit RGB888 的转换

  8bit RGB332 R2 R1 R0 G2 G1 G0 B1 B0

  24bit RGB888 R2 R1 R0 0 0 0 0 0 G2 G1 G0 0 0 0 0 0 B1 B0 0 0 0 0 0 0

  24bit RGB888 R2 R1 R0 R2 R1 R0 0 0 G2 G1 G0 G2 G1 G0 0 0 B1 B0 B1 B0 0 0 0 0

  24bit RGB888 R2 R1 R0 R2 R1 R0 R2 R1 G2 G1 G0 G2 G1 G0 G2 G1 B1 B0 B1 B0 B1 B0 0 0

  24bit RGB888 R2 R1 R0 R2 R1 R0 R2 R1 G2 G1 G0 G2 G1 G0 G2 G1 B1 B0 B1 B0 B1 B0 B1 B0

  看了这个,应该明白则么回事了吧,其中B分量,进行了四轮的补偿,达到要求。

16bit RGB565 -> 24bit RGB888 的转换代码:

16bit RGB565 R4 R3 R2 R1 R0 G5 G4 G3 G2 G1 G0 B4 B3 B2 B1B0

24ibt RGB888 R4 R3 R2 R1 R0 R2 R1 R0 G5 G4 G3 G2 G1 G0 G1G0 B4 B3 B2 B1 B0 B2 B1 B0

//rgb24 = (unsigned char*)malloc(width*3);
       //rgb16 = (unsigned short*)malloc(width*height*2);

 int x = 0, y = 0;
 /* RGB565 -> RGB888, compress */
 for (y = 0; y < height; y++)
 {
  for (x = 0; x < width; x++)
  {
   *(rgb24 + x*3+0) = ((*(rgb16 + y*width + x) & 0xf800)>> 8) & 0xff;
   *(rgb24 + x*3+1) = ((*(rgb16 + y*width + x) & 0x07e0)>> 3) & 0xff;
   *(rgb24 + x*3+2) = ((*(rgb16 + y*width + x) & 0x001f)<< 3) & 0xff;
  }
 }
        这里进行的是量化压缩(上面的概念),转换时rgb565的两个字节对应rgb888的三个字节,其中内部for循环里的& 0xf800是保证rgb565一个像素两个字节中高五位不变,然后右移8位,之后& 0xff保证右移之后低8位不变,其中后三位为0,这里有精度损失,最后把低8位赋值给rgb888的一个像素中的第一个字节;下面的就是保证rgb565两个字节中的中间六位转换成rgb888第二字节的前六位,后两位是0,保证rgb565两个字节中的最后5位转换成rgb888第三字节的前5位,后三位是0,这里所说的就是上面介绍的量化压缩原理,两个for循环实现的就是rgb545所有像素对rgb888所有像素的转换.

可能还有更优化的算法,这里也是参考师兄的程序,仅仅是看懂了而已,仅供参考!



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值