YUV422转RGB565源码及详解
2013-04-10 17:43
429 查看
只需调用compress_yuyv_to_rgb()函数即可实现图片格式由yuv422到rgb565的转换,其中,第一参数为LCD映射到用户空间的buffer,第二个参数为摄像头采集到一帧的图片数数据存放的buffer。
yuyv格式的图片中,y代表亮度,0最弱,255最亮,u和v代表颜色,u为蓝色(blue),即Cb,v为红色(red),即Cr。
rgb565格式的图片中,r代表红色,g代表绿色,b代表蓝色,565代表一个像素点占16位,即一个像素点占2个字节。rgb888代表一个像素点占24位。
此代码根据480*272分辨率的lcd来进行测试的,如分辨率不同,根据相应的数据修改代码。
int compress_yuyv_to_rgb(unsigned char *framebuffer,unsigned char *tempbuffer)
{
unsigned char *yuyv = framebuffer;//vd->framebuffer为开辟的640*480*2字节的内存空间
int z = 0 , i = 0, j = 0;
for(i = 0 ; i < 272 ; i++) //宽度的像素点数 480*0.6=288 //此处最大值可以增加1
{
for (j = 0; j < 480; j++) //长度的像素点数 640*0.75=480 //此处值如果减半,即240,则最后yuyv += 4相应的改为yuyv += 8,可达到双屏的效果,而且,外循环的272可以为480,扩大了摄像头的采集范围
{
int r, g, b;
int y, u, v;
short rgb;
//此处代码没研究明白,可能跟采样相关吧,大概执行为(yuy1v): yuvy1uvy2u1v1y3u1v1....
if (!z)
y = yuyv[0] << 8;
else
y = yuyv[2] << 8;
u = yuyv[1] - 128;
v = yuyv[3] - 128;
//yuv转rgb888
r = (y + (359 * v)) >> 8;
g = (y - (88 * u) - (183 * v)) >> 8;
b = (y + (454 * u)) >> 8;
r = (r > 255) ? 255 : ((r < 0) ? 0 : r); // RGB的范围为0~255,0为最弱,255为最亮
g = (g > 255) ? 255 : ((g < 0) ? 0 : g);
b = (b > 255) ? 255 : ((b < 0) ? 0 : b);
//rgb888转rgb565
r >>= 3; //RGB565格式中red占5位,green占6位,blue占5位,故需进行移位
g >>= 2;
b >>= 3;
rgb = (r<<11)|(g<<5)|(b);//生成一个2个字节长度的像素点,即rgb565
//赋给lcd映射的buffer
*tempbuffer++ = (char)rgb; //第一个字节
*tempbuffer++ = (char)(rgb >> 8); //第二个字节
if (z++)
{
z = 0;
yuyv += 4; //yuyv为四个,所以下一像素点从第五个字节开始
}
}
yuyv += (640-480)*2;//换行,即裁剪,因为摄像头采集的是640*480的,横屏640,但lcd横屏为480,多余的就裁剪了。
}
}
yuyv格式的图片中,y代表亮度,0最弱,255最亮,u和v代表颜色,u为蓝色(blue),即Cb,v为红色(red),即Cr。
rgb565格式的图片中,r代表红色,g代表绿色,b代表蓝色,565代表一个像素点占16位,即一个像素点占2个字节。rgb888代表一个像素点占24位。
此代码根据480*272分辨率的lcd来进行测试的,如分辨率不同,根据相应的数据修改代码。
int compress_yuyv_to_rgb(unsigned char *framebuffer,unsigned char *tempbuffer)
{
unsigned char *yuyv = framebuffer;//vd->framebuffer为开辟的640*480*2字节的内存空间
int z = 0 , i = 0, j = 0;
for(i = 0 ; i < 272 ; i++) //宽度的像素点数 480*0.6=288 //此处最大值可以增加1
{
for (j = 0; j < 480; j++) //长度的像素点数 640*0.75=480 //此处值如果减半,即240,则最后yuyv += 4相应的改为yuyv += 8,可达到双屏的效果,而且,外循环的272可以为480,扩大了摄像头的采集范围
{
int r, g, b;
int y, u, v;
short rgb;
//此处代码没研究明白,可能跟采样相关吧,大概执行为(yuy1v): yuvy1uvy2u1v1y3u1v1....
if (!z)
y = yuyv[0] << 8;
else
y = yuyv[2] << 8;
u = yuyv[1] - 128;
v = yuyv[3] - 128;
//yuv转rgb888
r = (y + (359 * v)) >> 8;
g = (y - (88 * u) - (183 * v)) >> 8;
b = (y + (454 * u)) >> 8;
r = (r > 255) ? 255 : ((r < 0) ? 0 : r); // RGB的范围为0~255,0为最弱,255为最亮
g = (g > 255) ? 255 : ((g < 0) ? 0 : g);
b = (b > 255) ? 255 : ((b < 0) ? 0 : b);
//rgb888转rgb565
r >>= 3; //RGB565格式中red占5位,green占6位,blue占5位,故需进行移位
g >>= 2;
b >>= 3;
rgb = (r<<11)|(g<<5)|(b);//生成一个2个字节长度的像素点,即rgb565
//赋给lcd映射的buffer
*tempbuffer++ = (char)rgb; //第一个字节
*tempbuffer++ = (char)(rgb >> 8); //第二个字节
if (z++)
{
z = 0;
yuyv += 4; //yuyv为四个,所以下一像素点从第五个字节开始
}
}
yuyv += (640-480)*2;//换行,即裁剪,因为摄像头采集的是640*480的,横屏640,但lcd横屏为480,多余的就裁剪了。
}
}
相关文章推荐
- hadoop作业初始化过程详解(源码分析第三篇) 推荐
- Epoll详解及源码分析
- Asp.net中图片存储数据库以及页面读取显示通用方法详解-附源码下载
- 第48课:Spark中的新解析引擎Catalyst源码Analyzer彻底详解
- 史上最详细的LinkedHashMap详解--源码分析
- Android 读书笔记:View的事件分发机制 源码详解 ------《Android开发艺术探索》
- intel dpdk api ring 模块源码详解
- MQTT---HiveMQ源码详解(二)结构与启动
- node源码详解(五)
- (二十八)Java工具类BooleanUtils源码详解
- Andriod 从源码的角度详解View,ViewGroup的Touch事件的分发机制
- 【SSH进阶之路】深入源码,详解Struts基本实现流程(七)
- jquery源码解析:jQuery数据缓存机制详解2
- ASP.NET Core MVC 源码学习:MVC 启动流程详解
- Android Asynchronous Http Client的用法实例(详解+源码)
- 史上最详细的ConcurrentHashMap详解--源码分析
- (一)java.io.DataInput接口及源码详解
- thrift之compiler源码详解-3