ffmpeg Windows下采集摄像头一帧数据,并保存为bmp图片 2016-09-28 00:00:00 广州睿丰德信息科技有限公司 阅读 睿丰德科技 专注RFID识别技术和条码识别技术与管理软件的集成项目。质量追溯系统、MES系统、金蝶与条码系统对接、用友与条码系统对接 这里请注意,在编译ffmpeg时,不要使用--disable-devices选项。 使用 --enable-encoder=rawvideo --enable-decoder=rawvideo 启用rawvideo codec。 代码如下: [cpp] view plaincopyprint? #include <stdlib.h> #include <stdio.h> #include <string.h> #include <libavformat/avformat.h> #include <libavcodec/avcodec.h> #include <libavdevice/avdevice.h> #include <libswscale/swscale.h> #include <windows.h> #include <time.h> #define MAX_INPUT_DEVICE_NUM 10 #ifdef _WIN32 int strcasecmp(const char *s1, const char *s2) { while ((*s1 != '\0') && (tolower(*(unsigned char *) s1) == tolower(*(unsigned char *) s2))) { s1++; s2++; } return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2); } int strncasecmp(const char *s1, const char *s2, unsigned int n) { if (n == 0) return 0; while ((n-- != 0) && (tolower(*(unsigned char *) s1) == tolower(*(unsigned char *) s2))) { if (n == 0 || *s1 == '\0' || *s2 == '\0') return 0; s1++; s2++; } return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2); } #endif void save_bmp(unsigned char * data,int data_size,int w,int h,FILE * out) { // 位图文件头 BITMAPFILEHEADER bmpheader; BITMAPINFO bmpinfo; int bit = 24; bmpheader.bfType = ('M' <<8)|'B'; bmpheader.bfReserved1 = 0; bmpheader.bfReserved2 = 0; bmpheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); bmpheader.bfSize = bmpheader.bfOffBits + w*h*bit/8; bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmpinfo.bmiHeader.biWidth = w; bmpinfo.bmiHeader.biHeight = 0-h; bmpinfo.bmiHeader.biPlanes = 1; bmpinfo.bmiHeader.biBitCount = bit; bmpinfo.bmiHeader.biCompression = BI_RGB; bmpinfo.bmiHeader.biSizeImage = 0; bmpinfo.bmiHeader.biXPelsPerMeter = 100; bmpinfo.bmiHeader.biYPelsPerMeter = 100; bmpinfo.bmiHeader.biClrUsed = 0; bmpinfo.bmiHeader.biClrImportant = 0; fwrite(&bmpheader,sizeof(BITMAPFILEHEADER),1,out); fwrite(&bmpinfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,out); fwrite(data,data_size,1,out); } int CaptureFromLocalCamera() { AVFormatContext *ic = NULL; AVFormatParameters in_fmt_para={0}; AVPacket packet; char buffer[MAX_PATH]={0}; int width = 0,height = 0; int ret,video_stream = -1,i=0; //查找输入(vfwcap)格式 AVInputFormat *in_fmt = av_find_input_format ("vfwcap"); if (in_fmt == NULL) { printf("not support input device vfwcap.\n"); return -1; } memset (&in_fmt_para, 0, sizeof(in_fmt_para)); //指定需要采集图像的高度 in_fmt_para.height = height; //指定需要采集图像的宽度 in_fmt_para.width = width; //设置帧率 av_parse_video_frame_rate(&in_fmt_para.time_base,"20"); //打开摄像头设备,从"0"到MAX_INPUT_DEVICE_NUM依次尝试打开 for( i=0 ; i < MAX_INPUT_DEVICE_NUM + 1; i++ ) { sprintf(buffer,"%d",i); ret = av_open_input_file ( &ic, buffer, in_fmt,sizeof(in_fmt_para),&in_fmt_para); if ( ret == 0 && ic) { break; } } //open success? if(!ic || ret != 0) { if(ic) av_close_input_file(ic); printf("can not open input file.\n"); return -2; } printf("input device no. is %d\n",i); //find the video stream for(i=0;i<ic ->nb_streams;i++) { if ( CODEC_TYPE_VIDEO == ic ->streams[i] ->codec ->codec_type ) { video_stream = i; break; } } if(video_stream < 0) { av_close_input_file(ic); printf("can not find a video stream.\n"); return -3; } //获取视频时间宽度和高度 width = ic ->streams[video_stream] ->codec ->width; height = ic ->streams[video_stream] ->codec ->height; printf("video size: %dx%d\n",width,height); //从摄像头获取图像数据 if( 0 == av_read_frame(ic,&packet)) { //find the decode codec AVCodec * decodec = avcodec_find_decoder(ic ->streams[video_stream] ->codec ->codec_id); if(decodec) { //open the decode codec if( 0 == avcodec_open(ic ->streams[video_stream] ->codec,decodec) ) { int got_picture = 0; AVFrame * frame = avcodec_alloc_frame(); avcodec_decode_video2(ic ->streams[video_stream] ->codec,frame,&got_picture,&packet); //decode success if(got_picture) { uint8_t * buffer = NULL; size_t buffer_size = 0; struct SwsContext *pSwsCtx=NULL; AVFrame * rgb_frame = avcodec_alloc_frame(); buffer_size = avpicture_get_size(PIX_FMT_BGR24,width,height); buffer = (uint8_t *)av_malloc(buffer_size); avpicture_fill((AVPicture*)rgb_frame,(uint8_t *)buffer,PIX_FMT_BGR24,width,height); //get swscale ctx pSwsCtx = sws_getContext( ic ->streams[video_stream] ->codec ->width, ic ->streams[video_stream] ->codec ->height, ic ->streams[video_stream] ->codec ->pix_fmt, width, height, PIX_FMT_BGR24, SWS_BILINEAR, NULL, NULL, NULL); if(pSwsCtx) { FILE *fp = NULL; SYSTEMTIME dt={0}; //图像格式转换 sws_scale( pSwsCtx, frame ->data, frame ->linesize, 0, ic ->streams[video_stream] ->codec ->height, rgb_frame ->data, rgb_frame ->linesize); //create the image file name GetLocalTime(&dt); srand(0); sprintf(buffer,"imgs/%04d_%02d_%02d %02d_%02d_%02d %02d.bmp",dt.wYear,dt.wMonth,dt.wDay,dt.wHour,dt.wMinute,dt.wSecond,rand()%30); // CreateDirectoryA("imgs",NULL); //open file fp = fopen(buffer, "wb"); if(fp) { save_bmp(rgb_frame ->data[0],rgb_frame ->linesize[0]*height,width,height,fp); fclose(fp); } //free sws ctx sws_freeContext(pSwsCtx); } //free buffer av_free(rgb_frame); av_free(buffer); } //free buffer av_free(frame); //close the decode codec avcodec_close(ic ->streams[video_stream] ->codec); } } } //close the input device av_close_input_file(ic); return 0; } int main() { //avcodec_init(); avcodec_register_all(); avdevice_register_all(); CaptureFromLocalCamera(); return 0; } RFID管理系统集成商 RFID中间件 条码系统中间层 物联网软件集成