- 摄像头配置
- 读取一帧
- 调用libjpeg库解压缩(没有的话可以在gith上下载自己编译)
- 保存为RGB24图像
- 下面是内存中摄像头读取的数据直接转存为RGB图片的源码。
- 输入:图像指针地址,图像长度(两个参数都能由V4L2读取一帧的时候获得)
#include <jpeglib.h> // 记得编译的时候-ljpeg
//convert mjpeg frame to RGB24
int MJPEG2RGB(uint8_t* data_frame, int bytesused)
{
// variables:
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
unsigned int width, height;
// data points to the mjpeg frame received from v4l2.
unsigned char *data = data_frame;
size_t data_size = bytesused;
// all the pixels after conversion to RGB.
unsigned char *pixels;// to store RBG 存放RGB结果
int pixel_size = 0;//size of one pixel
if ( data == NULL || data_size <= 0)
{
printf("Empty data!\n");
return -1;
}
uint8_t h1 = 0xFF;
uint8_t h2 = 0xD8;//jpg的头部两个字节
// if(*(data)!=h1 || *(data+1)==h2)
// {
// // error header
// printf("wrong header %d\n ",cnt);
// return -2;
// }
// ... In the initialization of the program:
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_mem_src(&cinfo, data, data_size);
int rc = jpeg_read_header(&cinfo, TRUE);
if(!(1==rc))
{
printf("Not a jpg frame.\n");
return -2;
}
jpeg_start_decompress(&cinfo);
width = cinfo.output_width;
height = cinfo.output_height;
pixel_size = cinfo.output_components; //3
int bmp_size = width * height * pixel_size;
pixels = (unsigned char *)malloc(bmp_size);
// ... Every frame:
while (cinfo.output_scanline < cinfo.output_height)
{
unsigned char *temp_array[] ={ pixels + (cinfo.output_scanline) * width * pixel_size };
jpeg_read_scanlines(&cinfo, temp_array, 1);
}
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
// Write the decompressed bitmap out to a ppm file, just to make sure
//保存为PPM6格式(P6 Pixmap Binary)
char fname[25] = { 0 }; // file name
if (FMT == V4L2_PIX_FMT_MJPEG)
{
sprintf(fname, "output_%d.ppm", cnt);//cnt 是用来计算的全局变量
char buf[50]; //for header
rc = sprintf(buf, "P6 %d %d 255\n", width, height);
FILE *fd = fopen(fname, "w");
fwrite(buf, rc, 1, fd);
fwrite(pixels, bmp_size, 1, fd);
fflush(fd);
fclose(fd);
}
free(pixels);// free
return 0;
}