c语言 v4l2 采集图片 拍照

  • V5_941088
    了解作者
  • 124.9KB
    文件大小
  • zip
    文件格式
  • 0
    收藏次数
  • VIP专享
    资源类型
  • 0
    下载次数
  • 2022-05-07 08:11
    上传日期
linux系统下 使用C语言, 使用v4l2 支持YUYV (YUV420格式) 保存为bmp图像,无需额外库。
v4l2-bmp.zip
  • v4l2-bmp
  • Debug
  • v4l2-bmp.d
    26B
  • v4l2-bmp
    129KB
  • v4l2-bmp.o
    167.2KB
  • subdir.mk
    656B
  • sources.mk
    390B
  • objects.mk
    231B
  • makefile
    962B
  • v4l2-bmp.c
    25.3KB
  • .cproject
    10.6KB
  • .project
    760B
内容介绍
/* * v4l2-bmp.c * * Created on: 2014年8月6日 * Author: ljw */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h rel='nofollow' onclick='return false;'> #include <getopt.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <malloc.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/time.h> #include <sys/mman.h> #include <sys/ioctl.h> #include <asm/types.h rel='nofollow' onclick='return false;'> #include <linux/videodev2.h> #define CAMERA_DEVICE "/dev/video0" #define CAPTURE_FILE "frame_yuyv_new.jpg" #define CAPTURE_RGB_FILE "frame_rgb_new.bmp" #define CAPTURE_show_FILE "a.bmp" #define VIDEO_WIDTH 640 #define VIDEO_HEIGHT 480 #define VIDEO_FORMAT V4L2_PIX_FMT_YUYV #define BUFFER_COUNT 4 typedef struct VideoBuffer { void *start; //视频缓冲区的起始地址 size_t length;//缓冲区的长度 } VideoBuffer; //位图文件头数据结构含有位图文件的类型,大小和打印格式等信息 //进行数据字节的对齐 #pragma pack(1) typedef struct BITMAPFILEHEADER { unsigned short bfType;//位图文件的类型, unsigned long bfSize;//位图文件的大小,以字节为单位 unsigned short bfReserved1;//位图文件保留字,必须为0 unsigned short bfReserved2;//同上 unsigned long bfOffBits;//位图阵列的起始位置,以相对于位图文件 或者说是头的偏移量表示,以字节为单位 } BITMAPFILEHEADER; #pragma pack() typedef struct BITMAPINFOHEADER//位图信息头类型的数据结构,用于说明位图的尺寸 { unsigned long biSize;//位图信息头的长度,以字节为单位 unsigned long biWidth;//位图的宽度,以像素为单位 unsigned long biHeight;//位图的高度,以像素为单位 unsigned short biPlanes;//目标设备的级别,必须为1 unsigned short biBitCount;//每个像素所需的位数,必须是1(单色),4(16色),8(256色)或24(2^24色)之一 unsigned long biCompression;//位图的压缩类型,必须是0-不压缩,1-BI_RLE8压缩类型或2-BI_RLE4压缩类型之一 unsigned long biSizeImage;//位图大小,以字节为单位 unsigned long biXPelsPerMeter;//位图目标设备水平分辨率,以每米像素数为单位 unsigned long biYPelsPerMeter;//位图目标设备垂直分辨率,以每米像素数为单位 unsigned long biClrUsed;//位图实际使用的颜色表中的颜色变址数 unsigned long biClrImportant;//位图显示过程中被认为重要颜色的变址数 } BITMAPINFOHEADER; VideoBuffer framebuf[BUFFER_COUNT]; //修改了错误,2012-5.21 int fd; struct v4l2_capability cap; struct v4l2_fmtdesc fmtdesc; struct v4l2_format fmt; struct v4l2_requestbuffers reqbuf; struct v4l2_buffer buf; unsigned char *starter; unsigned char *newBuf; struct BITMAPFILEHEADER bfh; struct BITMAPINFOHEADER bih; void create_bmp_header() { bfh.bfType = (unsigned short)0x4D42; bfh.bfSize = (unsigned long)(14 + 40 + VIDEO_WIDTH * VIDEO_HEIGHT*3); bfh.bfReserved1 = 0; bfh.bfReserved2 = 0; bfh.bfOffBits = (unsigned long)(14 + 40); bih.biBitCount = 24; bih.biWidth = VIDEO_WIDTH; bih.biHeight = VIDEO_HEIGHT; bih.biSizeImage = VIDEO_WIDTH * VIDEO_HEIGHT * 3; bih.biClrImportant = 0; bih.biClrUsed = 0; bih.biCompression = 0; bih.biPlanes = 1; bih.biSize = 40;//sizeof(bih); bih.biXPelsPerMeter = 0x00000ec4; bih.biYPelsPerMeter = 0x00000ec4; } int open_device() { /* 在linux下设备都是以文件的形式进行管理的 ioctl是设备驱动程序中对设备的I/O通道进行管理的函数int ioctl(int fd,int cmd,...)? 成功返回0,出错返回-1 其中fd--就是用户程序打开设备使用open函数返回的文件标识符 cmd--就是用户程序对设备的控制命令,至于后面都省略号,有或没有和cmd的意义相关 */ int fd; fd = open(CAMERA_DEVICE, O_RDWR, 0);// if (fd < 0) { printf("Open %s failed\n", CAMERA_DEVICE); return -1; } return fd; } void get_capability() {// 获取驱动信息 /* 控制命令VIDIOC_QUERYCAP 功能:查询设备驱动的功能; 参数说明:参数类型为V4L2的能力描述类型struct v4l2_capability; struct v4l2_capability { __u8 driver[16]; //i.e. "bttv" //驱动名称, __u8 card[32]; // i.e. "Hauppauge WinTV" // __u8 bus_info[32]; // "PCI:" + pci_name(pci_dev) //PCI总线信息 __u32 version; // should use KERNEL_VERSION() __u32 capabilities; // Device capabilities //设备能力 __u32 reserved[4]; }; 返回值说明: 执行成功时,函数返回值为 0; 函数执行成功后,struct v4l2_capability 结构体变量中的返回当前视频设备所支持的功能 例如支持视频捕获功能V4L2_CAP_VIDEO_CAPTURE或V4L2_CAP_STREAMING */ int ret = ioctl(fd, VIDIOC_QUERYCAP, &cap); if (ret < 0) { printf("VIDIOC_QUERYCAP failed (%d)\n", ret); return; } // Print capability infomations printf("------------VIDIOC_QUERYCAP-----------\n"); printf("Capability Informations:\n"); printf(" driver: %s\n", cap.driver); printf(" card: %s\n", cap.card); printf(" bus_info: %s\n", cap.bus_info); printf(" version: %08X\n", cap.version); printf(" capabilities: %08X\n\n", cap.capabilities); return; } void get_format() { /*获取当前视频设备支持的视频格式 控制命令 VIDIOC_ENUM_FMT 功能: 获取当前视频设备支持的视频格式 。 参数说明:参数类型为V4L2的视频格式描述符类型 struct v4l2_fmtdesc struct v4l2_fmtdesc { __u32 index; // Format number enum v4l2_buf_type type; // buffer type __u32 flags; __u8 description[32]; // Description string __u32 pixelformat; // Format fourcc __u32 reserved[4]; }; 返回值说明: 执行成功时,函数返回值为 0; */ int ret; fmtdesc.index=0; fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ret=ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc); while (ret != 0) { fmtdesc.index++; ret=ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc); } printf("--------VIDIOC_ENUM_FMT---------\n"); printf("get the format what the device support\n{ pixelformat = ''%c%c%c%c'', description = ''%s'' }\n",fmtdesc.pixelformat & 0xFF, (fmtdesc.pixelformat >> 8) & 0xFF, (fmtdesc.pixelformat >> 16) & 0xFF,(fmtdesc.pixelformat >> 24) & 0xFF, fmtdesc.description); return; } int set_format() { /* 控制命令VIDIOC_S_FMT 功能:设置视频设备的视频数据格式,例如设置视频图像数据的长、宽,图像格式JPEG、YUYV格式); 参数说明:参数类型为V4L2的视频数据格式类型struct v4l2_format; struct v4l2_format { enum v4l2_buf_type type; //数据流类型,必须永远是V4L2_BUF_TYPE_VIDEO_CAPTURE union { struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE struct v4l2_window win; // V4L2_BUF_TYPE_VIDEO_OVERLAY struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE struct v4l2_sliced_vbi_format sliced; // V4L2_BUF_TYPE_SLICED_VBI_CAPTURE __u8 raw_data[200]; // user-defined } fmt; }; struct v4l2_pix_format { __u32 width; // 宽,必须是16的倍数 __u32 height; // 高,必须是16的倍数 __u32 pixelformat; // 视频数据存储类型,例如是YUV4:2:2还是RGB enum v4l2_field field; __u32 bytesperline; __u32 sizeimage; enum v4l2_colorspace colorspace; __u32 priv; }; 返回值说明: 执行成功时,函数返回值为 0; 注意:如果该视频设备驱动不支持你所设定的图像格式,视频驱动会重�
评论
    相关推荐