- 论坛徽章:
- 0
|
本帖最后由 wcy0556 于 2010-08-15 17:25 编辑
这几天小弟正在做一个有关图片格式转换的课题,具体是这样的:将CMOS摄像头采集到的RGB565格式数据转换成JPG格式图片,以便在QT界面上显示。我的思路是这样:将RGB565->RGB888->JPG,但是最后生成的.jpg图片出现了花屏现象,百思不得其解,希望各位大侠帮帮忙!!
我的源码如下:
/*main.cpp*/
#include <QApplication>
#include "camtest1.cpp"
#define RGB565_RED 0xF800 /*R*/
#define RGB565_RED_BEST 0x3800
#define RGB565_GREEN 0x07E0 /*G*/
#define RGB565_GREEN_BEST 0x0060
#define RGB565_BLUE 0x001F /*B*/
#define RGB565_BLUE_BEST 0x0007
extern "C"{
#include <jpeglib.h>
#include <jerror.h>
}
#include <stdio.h>
int main(int argc, char **argv)
{
FILE* jpgFile;
unsigned short data[20480];
unsigned short *pdata=data;
unsigned short j=0;
unsigned short tmp1=0;
unsigned short tmp2=0;
unsigned short tmp3=0;
unsigned char buff[61440];/*存放RGB565->RGB888的三个数据*/
QApplication app(argc,argv);
try { /*try中包含抛出异常的模块*/
TFrameBuffer FrameBuffer;/*建立帧缓存对象*/
TVideo Video;
Video.FetchPicture();/*采集图像数据*/
FrameBuffer.DrawRect(Video);/*显示图像*/
/*for(int i=0;i<20;i++)
std::cerr << "the Video.Addr is"<< (int)(*(Video.Addr+i)) << std::endl;*/
for(unsigned short i=0;i<40960;i++)/*将摄像头输出的RGB565字节流转化为字流,便于下面的的格式转换*/
{
tmp1 = (unsigned short)(*(Video.Addr+i));
tmp1&=0x00FF;
/*std::cerr << "tmp1=" << tmp1 << std::endl;*/
tmp1 = (tmp1<<;
/*std::cerr << "tmp1<<8=" << tmp1 << std::endl;*/
tmp2 = (unsigned short)(*(Video.Addr+i+1));
tmp2&=0x00FF;
/*std::cerr << "tmp2=" << tmp2 << std::endl;*/
data[j] = tmp1+tmp2;
/*std::cerr << data[j] << std::endl;*/
i++;
j++;
if(j==20479)
{
j=0;
std::cerr << " 16 is OK" << std::endl;
}
}
for(unsigned short i=0;i<20480;i++)/*将RGB565数据转化为RGB888数据*/
{
tmp3 = *pdata;
buff[i*3+0]=(tmp3 & RGB565_RED)>>11;
buff[i*3+0]<<=3;
/*buff[i*3+0]|=((tmp3 & RGB565_RED_BEST)>>11);*//*R4R3R2R1R0R2R1R0*/
buff[i*3+1]=(tmp3 & RGB565_GREEN)>>5;
buff[i*3+1]<<=2;
/*buff[i*3+1]|=((tmp3 & RGB565_GREEN_BEST)>>5);*//*G5G4G3G2G1G0G1G0*/
buff[i*3+2]=(tmp3 & RGB565_BLUE);
buff[i*3+2]<<=3;
/*buff[i*3+2]|=(tmp3 & RGB565_BLUE_BEST);*//*B4B3B2B1B0B2B1B0*/
/* bmp24=(buff[i*3+0]<<16)+(buff[i*3+1]<<+buff[i*3+2];*//*数据存入RGB888数组*/
pdata++;
if(i==20479)
{
pdata=data;
std::cerr << " RGB888 is OK" << std::endl;
}
}
/*调用JEPG库,将图片压缩成JPEG格式*/
struct jpeg_compress_struct jcs;
struct jpeg_error_mgr jem;
jcs.err = jpeg_std_error(&jem);
jpeg_create_compress(&jcs);
jpgFile=fopen("camera.jpg","wb"
if (jpgFile==NULL)
{
free(buff);
return 0;
}
jpeg_stdio_dest(&jcs, jpgFile);
jcs.image_width = 160; /*为图的宽和高,单位为像素*/
jcs.image_height = 128;
jcs.input_components = 3; /*色彩通道数 在此为1,表示灰度图, 如果是彩色位图,则为3*/
jcs.in_color_space = JCS_RGB; /*色彩空间 ,JCS_GRAYSCALE表示灰度图, JCS_RGB 表示彩色图像*/
jpeg_set_defaults(&jcs);
jpeg_set_quality(&jcs, 80, true);/*压缩质量*/
/*上面的工作准备完成后,就可以压缩了,压缩过程非常简单,首先调用 jpeg_start_compress,
然后可以对每一行进行压缩,也可以对若干行进行压缩,甚至可以对整个的图像进行一次压缩,如下:*/
jpeg_start_compress(&jcs, true);
JSAMPROW row_pointer[1]; /*一行位图*/
int row_stride; /*每一行的字节数*/
row_stride = jcs.image_width*3; /*如果不是索引图,此处需要乘以3*/ /*480*/
/*对每一行进行压缩*/
while(jcs.next_scanline <12
{
row_pointer[0] = & buff[jcs.next_scanline * row_stride];
jpeg_write_scanlines(&jcs, row_pointer, 1);
}
jpeg_finish_compress(&jcs);//压缩完成后,记得要调用jpeg_finish_compress函数
/*5、最后就是释放压缩工作过程中所申请的资源了,主要就是jpeg压缩对象,由于在本例中我是直接用的局部变量,
所以只需调用jpeg_destroy_compress这个函数即可,如下:*/
jpeg_destroy_compress(&jcs);
/*FrameBuffer.DrawRect(Video);*/
while(1) ;
}
}catch (TError bitand e) { //捕获异常
e.Output();
return 1;
}
std::cerr << "show picture" << std::endl;
return app.exec();
}
结果生成的有问题的图片点击图片栏即可看到。
我觉得问题应该处在RGB数据转换成JPG格式图片的那部分里面,但是总是无法解决,希望各位兄弟姐妹可以帮助,小弟不胜感激!!! |
|