RGB配色原理(ARM92440)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

RGB配色原理
在操作LCD屏显示的时候,我们都需要对320x240个像素点填充颜色,今天就来研究下所谓的RGB配色原理。

在这之前,我们都知道所谓对320x240个像素点填充颜色其实就是将某个数值赋给LCD_BUFFER[(y)][(x)],让我们先来看看TFT LCD单个象素的显示数据输出的函数:
void PutPixel(U32 x,U32 y, U32 c )
{
if ( (x < SCR_XSIZE_TFT) && (y < SCR_YSIZE_TFT) )
LCD_BUFFER[(y)][(x)] = c;
}
这里SCR_XSIZE_TFT 和SCR_YSIZE_TFT以前我们研究过,是在使用3.5寸屏幕的时候的,屏幕的像素边界值分别是320和240。

这里我们是把c赋给屏幕的LCD_BUFFER,c的值就是对应颜色的数值。

此外我们在研究Paint_Bmp函数的时候,通过c = bmp[p+1] | (bmp[p]<<8)语句我们知道c的值是16位。

此外我们还可以通过其他途径知道c到底是多少位的。

例如我们出厂程序的Lcd_TFT_Test实验中曾经有5次刷屏,我们曾经用到过清屏语句:Lcd_ClearScr( (0x00<<11) | (0x00<<5) | (0x00) ) ; //Black
Lcd_ClearScr( (0x1f<<11) | (0x3f<<5) | (0x1f) ) ; //White
Lcd_ClearScr( (0x00<<11) | (0x00<<5) | (0x1f) ) ; //Blue
Lcd_ClearScr( (0x00<<11) | (0x3f<<5) | (0x00) ) ; //Green
Lcd_ClearScr( (0x1f<<11) | (0x00<<5) | (0x00) ) ; //Red
这里分别代表黑白蓝绿红五种颜色,对应的数值就在函数括号内的参数值。

根据这些数值我们也知道c是16位的(位数最高的0x00<<11是16位数)。

知道了我们的颜色数值数据c是十六位数据,但是并知道它是怎么样分别构成的上面的black、white、blue、green、red等颜色,以及我们图片上面每一个像素点的丰富的颜色。

针对此,
下面就找了一些关于液晶显示的原理以及RGB原理的基础知识的资料。

一、液晶显示原理简介
液晶是一种介于固态和液态之间的物质,是具有规则性分子排列的有机化合物。

如果把它加热会呈现透明状的液体状态,把它冷却则会出现结晶颗粒的混浊固体状态,具有液体与晶体的特性,故称之为“液晶”。

液晶显示的原理简单地说,就是将置于两个电极之间的液晶通电,液晶分子的排列顺序在电极通电时会发生改变,从而改变透射光的光路,实现对影像的控制。

大家都知道TFT液晶显示器的每个点都由红绿蓝三部分组成,简单举例来讲就是:当R.G.B都为255时(针对24位颜色值,我们此处使用的是16位颜色值),色彩为透明(即背景灯颜色为纯白);RGB都为0时,为黑色。

用一个粗糙的比喻来帮助大家理解和记忆就是:当给RGB的每一位都通高电平的时候,液晶通电融化,呈现为透明状态,此时,大家看到的就是背景灯的颜色,纯白(色);当每一位都接低电平的时候,液晶完全固化,完全不透明,背景灯被完全遮盖,此时,大家就看到屏幕呈现为纯黑(色)。

同理有:
当我们的R位都为高电平,G位和B位都为低电平的时候,显示为纯红;
当我们的G位都为高电平,R位和B位都为低电平的时候,显示为纯绿;
当我们的B位都为高电平,R位和G位都为低电平的时候,显示为纯蓝;
(注意:此处仅仅是比喻,真实原理要比这复杂得多。

要想搞懂其中的真正原理请参考专业手册。


二、、RGB颜色原理
RGB颜色原理是用三种原色──红色、绿色和蓝色的色光以不同的比例相加,以产生多种多样的色光。

RGB模式的命名来自于三种相加原色的首字母(Red(红),Green(绿),Blue (蓝))。

配色原理示意图:
红色+绿色=黄色
绿色+蓝色=青色
红色+蓝色=品红
举个列子:红光与绿光按某种比例复合,对三种锥状细胞刺激后产生的色觉可与眼睛对单纯的黄光的色觉等效。

但决不能认为红光与绿光按某种比例复合后生成黄光,或黄光是由红光和绿光复合而成的。

像这种采用红绿蓝三基色按照不同的比例相加合成混色称为相加混色。

这里叠加生成的黄色、青色、品红都是由两种基色相混合而成,所以它们又称相加二次色。

三、常见的1600万色标准
我们也可以称之为24比特模式。

1600万色的意思就是2^24=16777216。

每像素24位(bits per pixel,bpp)编码的RGB值:使用三个8位无符号整数(0到255)表示红色、绿色和蓝色的强度。

这是当前主流的标准表示方法,用于真彩色和JPEG或者TIFF等图像文件格式里的通用颜色交换。

它可以产生一千六百万种颜色组合,对人眼来说其中很多已经分辨不开。

在这种模式中有 16 种基本颜色,它们分别是:
四、常见的6.5万色标准
也可以称之为16比特模式。

也正是我们这里使用的模式。

而6.5万色的意思就是2^16=65536。

16比特模式分配给每种原色各为5比特,其中绿色为6比特,因为人眼对绿色分辨的色调更精确。

(但某些特殊情況下每种原色各佔5比特,余下的1比特不使用。

)所以,我们这里使用的应该是RGB为5:6:5模式。

搞明白这一点之后,再来分析c=(0x1f<<11)|(0x00<<5)|(0x00):
0x1f<<11=11111 000000 00000
0x00<<5 = 00 000000 00000
0x00= 000 00000
这三个数或之后得到:11111 000000 00000 其中R位都为高电平,G位和B 位都为低电平的时候,显示为纯红。

之所以左移11位和5位,其原因就是这里的RGB采用的是5:6:5模式。

在这种模式下:
Red: (0x1f<<11)|(0x00<<5)|(0x00)其实就是二进制数:11111 000000 00000 Green:(0x00<<11)|(0x3f<<5)|(0x00)其实就是二进制数:00000 111111 00000 Bule: (0x00<<11)|(0x00<<5)|(0x1f)其实就是二进制数:00000 000000 11111 White:(0x1f<<11)|(0x3f<<5)|(0x1f)其实就是二进制数:11111 111111 11111 Black:(0x00<<11)|(0x00<<5)|(0x00)其实就是二进制数:00000 000000 00000 下面来分析下,为什么要左移11位和5位:
首先我们知道RGB采用的是5:6:5模式。

所以16位数据的前5位我们让或的第一组8位数据中的后5位来表示,我
们知道8位数据中的后5位最高位为第5位,为了让8位数据后5位到达16位
数据的前5位,即让8位数据中第5位变为16位数据的第16位,我们需要左移11位就可以满足,因此第一组8位数据的高3位是没用的,我们用0代替,而后5位才是赋值必须的,这样我们就知道第一组8位数据是从0x00到0x1f。

同样的16位数据的中间6位我们让或的第二组8位数据中的后6位来表示,我们知道8位数据中的后6位最高位为第6位,为了让8位数据的后6位到达16位数据的中间6位,即让8位数据中第6位变为16位数据的第11位,我们需要左移5位就可以满足,而8位数据的高2位没用且在或的过程中不能影响16位数据的高5位,我们用0代替,后6位才是赋值必须的,这样我们就知道第二组8位数据是从0x00到0x3f。

同样的16位数据的最后5位我们让或的第三组8位数据中的后5位来表示,我们知道8位数据中的后5位最高位为第5位,为了让8位数据的后5位到达16位数据的最后5位,即让8位数据中第5位变为16位数据的第5位,我们不需要移动只用原数就可以满足,而8位数据的高3位没用且在或的过程中不能影响16位数据的中间6位,我们用0代替,后5位才是赋值必须的,这样我们就知道第三组8位数据是从0x00到0x1f。

到此我们对配色原理基本掌握了,下面我们便可以根据原理编写一段程序。

实现功能:1到32行像素点,显示红色且逐渐加深;33行到95行像素点,显示绿色且逐渐加深;96行到126行像素点,显示蓝色且逐渐加深;127行到160行像素点,显示黄色且逐渐加深;161行到200行像素点,显示青色且逐渐加深;201行到240行像素点,显示品红且逐渐加深;即出现宽度不一的颜色不一且每种颜色渐深的彩条带。

附试验代码如下:
while(1)
{
for(ii=0;ii<32;ii++){
Glib_Line(0, ii, 320, ii,(ii<<11) | (0<<5) | (0));//红色,逐渐加深
}
for(ii=32;ii<95;ii++){
Glib_Line(0, ii, 320, ii,(0<<11)|((ii-31)<<5)|(0));//绿色,逐渐加深
}
for(ii=95;ii<126;ii++){
Glib_Line(0, ii,320, ii,(0<<11)|(0<<5)|(ii-96));//蓝色,逐渐加深
}
for(ii=126;ii<160;ii++){
Glib_Line(0, ii, 320, ii,(0x1f<<11)|(0x3f<<5)|(0));//红色+绿色=黄色
}
for(ii=160;ii<200;ii++){
Glib_Line(0, ii, 320, ii,(0<<11)|(0x3f<<5)|(0x1f));//绿色+蓝色=青色
}
for(ii=200;ii<240;ii++){
Glib_Line(0, ii, 320, ii,(0x1f<<11)|(0<<5)|(0x1f));//红色+蓝色=品红
}
}。

相关文档
最新文档