本文内容不是完全原创,参考了网上部分精华,做了整理。

RGB色彩模式(也翻译为“红绿蓝”,比较少用)是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)

三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道

的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。

就RGB888->RGB565而言:其转换的具体思路如下:(注:只代表个人的方法)1.取RGB888中第一个字节的高5位作为转换后的RGB565的第二个字节的高5位2.取RGB888中第二个字节的高3位作为转换后的RGB565第二个字节的低3位3.取RGB888中第二个字节的第4--6位,作为转换后的RGB565第一个字节的高3位4.取RGB888中第二个字节的第三个字节的高5位作为转换后的RGB565第一个字节的低5位就RGB565->RGB888而言:RGB565的存储方式为:R4 R3 R2 R1 R0 G5 G4 G3 G2 G1 G0 B4 B3 B2 B1 B01.取RGB565第一个字节中低5位作为RGB888的高5位2.取RGB565第二个字节中的低3位,将其左移5位,作为RGB888第二个字节的高5位3.取RGB565第一个字节的高3位将其右移3位,作为RGB888第二个字节的4--6位4.取RGB565第二个字节中的高5位作为RGB888第三个字节。

细心地哥们一定会发现如果我们是低位往高位上转的话,就存在一些数据精度的丢失问题,

在网上查了写资料,借鉴了一下别人的方法;所谓的量化补偿,讲一下量化压缩与量化补偿吧

在进行色彩格式转换的时候,经常会遇到色彩量化位数的改变,比如说从 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 B016bit 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 B024ibt RGB888 R4 R3 R2 R1 R0 0 0 0 G5 G4 G3 G2 G1 G0 0 0 B4 B3 B2 B1 B0 0 0 024ibt 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. 如果仍然有未填充的位,继续使用原始数据的低位进行循环补偿

按照上面的图,我们大体知道了 RGB888 -> RGB565是怎么压缩的,也知道了RGB565- > RGB888

是怎么做补偿的,接下来就从代码的角度看看我们具体如何实现这样的转换。

代码:

(rr , gg, bb是属于byte类型,一字节大小)

(1) RGB565 -> RGB888

rr =byte[1] &0xf8;

gg = (byte[1] <<5) | ((byte[0] &0xe0) >>3);

bb = byte[0] <<3;

// 补偿

rr = rr | ((rr & 0x38) >>3);

gg = gg | ((gg & 0x0c) >>2);

bb = bb | ((bb & 0x38) >>3);

(2) RGB888 -> RGB555

for(intj = 0; j

{

WORD*pTemp = (WORD*)(pData + WIDTHBYTES(bmih.biWidth * 16) * j);

for(inti = 0; i

{

#if 1

*pTemp++ = ((WORD)(*pR++ <> 3) & 0x001f);

#else

intnR = (*pR++ + 4) >> 3;

intnG = (*pG++ + 2) >> 2;

intnB = (*pB++ + 4) >> 3;

if(nR > 31) nR = 31;

if(nG > 63) nG = 63;

if(nB > 31) nB = 31;

*pTemp++ = (nR <

#endif

}

}

以下是另外的实现方式 ( 注意处理数据的类型)

#define RGB565_MASK_RED 0xF800

#define RGB565_MASK_GREEN 0x07E0

#define RGB565_MASK_BLUE 0x001F

rgb5652rgb888 :

unsigned short*pRGB16 = (unsignedshort*)lParam;

for(inti=0; i<176*144; i++)

{

unsigned shortRGB16 = *pRGB16;

g_rgbbuf[i*3+2] = (RGB16&RGB565_MASK_RED) >> 11;

g_rgbbuf[i*3+1] = (RGB16&RGB565_MASK_GREEN) >> 5;

g_rgbbuf[i*3+0] = (RGB16&RGB565_MASK_BLUE);

g_rgbbuf[i*3+2] <<= 3;

g_rgbbuf[i*3+1] <<= 2;

g_rgbbuf[i*3+0] <<= 3;

pRGB16++;

}

另一种:rgb5652rgb888(unsignedchar*image,unsignedchar*image888)

{

unsigned charR,G,B;

B=(*image) & 0x1F;//000BBBBB

G=( *(image+1) <> 5 ) & 0x07 ;//得到00GGGGGG00

R=( *(image+1) >> 3 ) & 0x1F; //得到000RRRRR

*(image888+0)=B * 255 / 63; // 把5bits映射到8bits去,自己可以优化一下算法,下同

*(image888+1)=G * 255 / 127;

*(image888+2)=R * 255 / 63;

}

本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。

R8 = ( R5 * 527 + 23 ) >> 6;

G8 = ( G6 * 259 + 33 ) >> 6;

B8 = ( B5 * 527 + 23 ) >> 6;

It uses only: MUL, ADD and SHR -> so it is pretty fast! From the other side it is compatible in 100% to floating point mapping with proper rounding:// R8 = (int) floor( R5 * 255.0 / 31.0 + 0.5);

// G8 = (int) floor( G6 * 255.0 / 63.0 + 0.5);

// B8 = (int) floor( R5 * 255.0 / 31.0 + 0.5);

Some extra cents: If you are interested in 888 to 565 conversion, this works very well too:R5 = ( R8 * 249 + 1014 ) >> 11;

G6 = ( G8 * 253 + 505 ) >> 10;

B5 = ( B8 * 249 + 1014 ) >> 11;

(这组我看不懂,也没用过,但有人说是可用的,在此转给大家看看)

关于上面按比例转到8 bit的方法 ( 255 / 63 ), 我看到了另外一个实例,也转过来下:

#include

#include

using namespace std;

using namespace cv;

#define RED_MASK 0xF800

#define GREEN_MASK 0x07E0

#define BLUE_MASK 0x001F

int main(int argc, char* argv[])

{

IplImage *rgb565Image = cvCreateImage(cvSize(800, 480), IPL_DEPTH_16U, 1);

IplImage *rgb888Image = cvCreateImage(cvSize(800, 480), IPL_DEPTH_8U, 3);

unsigned short* rgb565Data = (unsigned short*)rgb565Image->imageData;

int rgb565Step = rgb565Image->widthStep / sizeof(unsigned short);

uchar* rgb888Data = (uchar*)rgb888Image->imageData;

float factor5Bit = 255.0 / 31.0;

float factor6Bit = 255.0 / 63.0;

for(int i = 0; i < rgb565Image->height; i++)

{

for(int j = 0; j < rgb565Image->width; j++)

{

unsigned short rgb565 = rgb565Data[i*rgb565Step + j];

uchar r5 = (rgb565 & RED_MASK) >> 11;

uchar g6 = (rgb565 & GREEN_MASK) >> 5;

uchar b5 = (rgb565 & BLUE_MASK);

// round answer to closest intensity in 8-bit space...

uchar r8 = floor((r5 * factor5Bit) + 0.5);

uchar g8 = floor((g6 * factor6Bit) + 0.5);

uchar b8 = floor((b5 * factor5Bit) + 0.5);

rgb888Data[i*rgb888Image->widthStep + j] = r8;

rgb888Data[i*rgb888Image->widthStep + (j + 1)] = g8;

rgb888Data[i*rgb888Image->widthStep + (j + 2)] = b8;

}

}

return 0;

}

//-------------------------------------------------------------------

//转换

staticintrgb565_to_rgb888(constvoid* psrc,intw,inth,void* pdst)

{

intsrclinesize = UpAlign4(w * 2);

intdstlinesize = UpAlign4(w * 3);

constunsignedchar* psrcline;

constunsignedshort* psrcdot;

unsigned char* pdstline;

unsigned char* pdstdot;

inti,j;

if(!psrc || !pdst || w <= 0 || h <= 0) {

printf("rgb565_to_rgb888 : parameter error\n");

return-1;

}

psrcline = (constunsignedchar*)psrc;

pdstline = (unsigned char*)pdst;

for(i=0; i

psrcdot = (constunsignedshort*)psrcline;

pdstdot = pdstline;

for(j=0; j

//565 b|g|r -> 888 r|g|b

*pdstdot++ = (unsigned char)(((*psrcdot) >> 0 ) <

*pdstdot++ = (unsigned char)(((*psrcdot) >> 5 ) <

*pdstdot++ = (unsigned char)(((*psrcdot) >> 11) <

psrcdot++;

}

psrcline += srclinesize;

pdstline += dstlinesize;

}

return0;

}

staticintrgb888_to_rgb565(constvoid* psrc,intw,inth,void* pdst)

{

intsrclinesize = UpAlign4(w * 3);

intdstlinesize = UpAlign4(w * 2);

constunsignedchar* psrcline;

constunsignedchar* psrcdot;

unsigned char* pdstline;

unsigned short* pdstdot;

inti,j;

if(!psrc || !pdst || w <= 0 || h <= 0) {

printf("rgb888_to_rgb565 : parameter error\n");

return-1;

}

psrcline = (constunsignedchar*)psrc;

pdstline = (unsigned char*)pdst;

for(i=0; i

psrcdot = psrcline;

pdstdot = (unsigned short*)pdstline;

for(j=0; j

//888 r|g|b -> 565 b|g|r

*pdstdot =  (((psrcdot[0] >> 3) & 0x1F) <

|(((psrcdot[1] >> 2) & 0x3F) <

|(((psrcdot[2] >> 3) & 0x1F) <

psrcdot += 3;

pdstdot++;

}

psrcline += srclinesize;

pdstline += dstlinesize;

}

return0;

}

java rgb565转rgb888_RGB565 与 RGB888的相互转换相关推荐

  1. RGB565 与 RGB888的相互转换

    本文内容不是完全原创,参考了网上部分精华,做了整理. RGB色彩模式(也翻译为"红绿蓝",比较少用)是工业界的一种颜色标准,是通过对红(R).绿(G).蓝(B) 三个颜色通道的变化 ...

  2. jaxb java xml序列化_XML编程总结(六)——使用JAXB进行java对象和xml格式之间的相互转换...

    (六)使用JAXB进行java对象和xml格式之间的相互转换 JAXB能够使用Jackson对JAXB注解的支持实现(jackson-module-jaxb-annotations),既方便生成XML ...

  3. RGB565,RGB555, RGB888,RGB32转换

    关于RGB565,RGB555, RGB888,RGB32的转换,在我的前一篇博文中我已经介绍过了关于RGB565->RGB888的步骤和思想.    今天上午又研究了一个上午,就谢了下来,希望 ...

  4. java中的 BigDecimal 和 String 的相互转换

    例子1,string 转BigDecimalpublic class Test{ public static void main(String[] arg) { String str1="2 ...

  5. java DTO对象与PO对象的相互转换

    2018-09-27 10:27:50 前言: 在实际开发中往往需要DTO对象与PO对象的相互转换: 先说说什么是DTO对象吧,个人觉得DTO就是PO的扩展而已,PO专门指向数据库,DTO作扩展(字段 ...

  6. java时间,日期,毫秒值,String的相互转换总结

    java时间日期的各种转换总结以及应用实例 由于工作中经常要用到时间,日期,以及当前时间的毫秒值等 很多时候涉及到了它们之间的相互转换,今天就好好的总结一下. 首先基本介绍一下java中有关时间,日期 ...

  7. java中字符数组和字符串的相互转换

    Java中String类很强大,好好学习它,对初学者很重要. 字符串和字符数组的转换是很常见的,请看下面代码. [java] view plaincopy char[]   a={ 'a ', 'b  ...

  8. java对象与json对象间的相互转换的方法

    String json=JSON.toJSONString(user);//关键 1.简单的解析json字符串 首先将json字符串转换为json对象,然后再解析json对象,过程如下. 1 JSON ...

  9. Java实现XLS和XLSX之间的相互转换

    文章目录 前言 一.程序环境 二.格式转换 1.将XLS转换为XLSX 代码示例 效果图 2.将XLSX转换为XLS 代码示例 效果图 前言 当你在较新版本的Microsoft Excel中打开一个X ...

  10. java map转bean_javaBean与map的相互转换

    1.通过json工具先将bean转换为json,再将json转换为map,这种方式效率很低,不推荐 2.通过java反射,获取bean类的属性和值,再转换到map对应的键值对中,这种方法次之,但稍微有 ...

最新文章

  1. Foundation ActionScript 3.0.With Flash CS3 And Flex ..
  2. Android Volley完全解析2:使用Volley加载网络图片
  3. 扩展筛选LightOj 1054 Efficient Pseudo Code
  4. 文字处理的标签及属性
  5. 【计算机网络】详解HttpURLConnection
  6. 数组实用类:Arrays
  7. tcp client.cs
  8. python递归实例_python实现递归实例代码
  9. 环信webIM即时通讯学习笔记
  10. ncbi和ensembl上的序列下载
  11. android 手机 优化,安卓手机超级优化技巧,流畅度飙升50%
  12. 蚂蚁森林在沙漠种植了5552万棵树,原来我也在做一件改变世界
  13. xLua热更新(二)实现热更新
  14. JavaScript - 你见过 [].slice.call() 吗?
  15. 绘制图像灰度直方图——将图像的灰度分布可视化方法总结
  16. css除法,CSS calc()百分比余数乘除法
  17. ASP.Net0626快播影院视频网的设计与实现
  18. OpenCV(4.0.0) Error: Assertion failed (dst.data == (uchar*)dst_ptr) in cvShowImage
  19. idea打开多个文件多排显示
  20. 转:数据库访问性能优化

热门文章

  1. jq ajax input file,基于jq的input file文件上传
  2. UNI-APP获取手机MAC地址
  3. 阿铭Linux_网站维护学习笔记201903015
  4. css怎么写仿粗体,在CSS中字体加粗要怎么做?
  5. python实现MD5加密工具
  6. 阿里云短信接口实现模板
  7. Chrome插件开发(chrome-extension)
  8. ps安装插件提示“无法加载扩展,因为它未正确签署”怎么办?PS插件未经签署解决方法
  9. 双拼输入法是个啥以及我是如何学会使用它的
  10. 文献管理工具EndNote X8 破解版,Windows版