linux下摄像头抓图源码
/****************************************************/
/* */
/* v4lgrab.h */
/* */
/****************************************************/
#ifndef __V4LGRAB_H__
#define __V4LGRAB_H__
#define WIDTHBYTES(i) ((i+31)/32*4)
#include <stdio.h>
//typedef enum { FALSE = 0, TRUE = 1, O67
//#define SWAP_HL_WORD(x) {(x) = ((x)<<8) | ((x)>>8);}
//#define SWAP_HL_DWORD(x) {(x) = ((x)<<24) | ((x)>>24) | (((x)&0xff0000)>>8) | (((x)&0xff00)<<8);}
#define FREE(x) if((x)){free((x));(x)=NULL;}
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef struct tagBITMAPFILEHEADER{
WORD bfType; // the flag of bmp, value is "BM"
DWORD bfSize; // size BMP file ,unit is bytes
DWORD bfReserved1; // 0
DWORD bfReserved2; //0
DWORD bfOffBits; // must be 54
}BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER{
DWORD biSize; // must be 0x28
DWORD biWidth; //
DWORD biHeight; //
WORD biPlanes; // must be 1
WORD biBitCount; //
DWORD biCompression; //
DWORD biSizeImage; //
DWORD biXPelsPerMeter; //
DWORD biYPelsPerMeter; //
DWORD biClrUsed; //
DWORD biClrImportant; //
}BITMAPINFOHEADER;
typedef struct tagRGBQUAD{
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
}RGBQUAD;
#if defined(__cplusplus)
extern "C" { /* Make sure we have C-declarations in C++ programs */
#endif
//if successful return 1,or else return 0
int openVideo();
int closeVideo();
//data 用来存储数据的空间, size空间大小
void getVideoData(unsigned char *data, int size);
#if defined(__cplusplus)
}
#endif
#endif //__V4LGRAB_H___
//-------------------------------------------------------------------------------
/****************************************************/
/* */
/* v4lgrab.c */
/* */
/****************************************************/
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <linux/types.h>
#include <linux/videodev.h>
#include "v4lgrab.h"
#define TRUE 1
#define FALSE 0
#define FILE_VIDEO "/dev/video0"
#define IMAGEWIDTH 640
#define IMAGEHEIGHT 480
static int fd;
static struct video_capability cap;
static struct video_window win;
static struct video_picture vpic;
static struct video_mmap mapbuf;
int openVideo()
{
//Open video device
fd = open(FILE_VIDEO, O_RDONLY);
if (fd < 0) {
perror(FILE_VIDEO);
return (FALSE);
}
//Get capabilities
if (ioctl(fd, VIDIOCGCAP, &cap) < 0) {
perror("VIDIOGCAP");
printf("(" FILE_VIDEO " not a video4linux device?)\n");
close(fd);
return (FALSE);
}
printf("devicename -->%s\n",cap.name);
printf("devicetape -->%d\n",cap.type);
printf("channels -->%d\n",cap.channels);
printf("maxwidth -->%d\n",cap.maxwidth);
printf("maxheith -->%d\n",cap.maxheight);
printf("minwidth -->%d\n",cap.minwidth);
printf("minheith -->%d\n",cap.minheight);
//Get the video overlay window
if (ioctl(fd, VIDIOCGWIN, &win) < 0) {
perror("VIDIOCGWIN");
close(fd);
return (FALSE);
}
//Set the video overlay window
win.width = IMAGEWIDTH;
win.height = IMAGEHEIGHT;
if(ioctl(fd, VIDIOCSWIN, &win) <0) {
perror("VIDIOCSWIN");
close(fd);
return (FALSE);;
}
//Get picture properties
if (ioctl(fd, VIDIOCGPICT, &vpic) < 0) {
perror("VIDIOCGPICT");
close(fd);
return (FALSE);
}
//mapbuf.width=600;
//mapbuf.height=480;
if (cap.type & VID_TYPE_MONOCHROME) {
} else {
vpic.depth=32;
//常用的颜色深度是1位、8位、24位和32位。1位有两个可能的数值:0或1。较大的颜色深度(每像素信息的位数更多)意味着数字图像具有较多的可用颜色和较精确的颜色表示
vpic.palette=VIDEO_PALETTE_RGB24;
vpic.brightness=5000;//3000-12000比较合适
vpic.colour=65535;
vpic.whiteness=65535;//65-65535差别不大
if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
printf("Unable to find a supported capture format.\n");
return (FALSE);
}
}
return (TRUE);
}
int closeVideo()
{
if(fd != -1) {
close(fd);
return (TRUE);
}
return (FALSE);
}
void getVideoData(unsigned char *data, int size)
{
size = read(fd, data, size);
}
//-------------------------------------------------------------------------------
/****************************************************/
/* */
/* temp_get.c */
/* */
/****************************************************/
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <linux/types.h>
#include <linux/videodev.h>
#include "v4lgrab.h"
#define BMP "image2.bmp"
#define IMAGEWIDTH 640
#define IMAGEHEIGHT 480
int main(int argc, char ** argv)
{
FILE * fp;
BITMAPFILEHEADER bf;
BITMAPINFOHEADER bi;
unsigned char * buffer;
int i;
fp = fopen(BMP, "wb");
if(!fp){
perror(BMP);
exit(1);
}
if(openVideo() == -1) {
return(-1);
}
//Set BITMAPINFOHEADER
bi.biSize = 40;
bi.biWidth = IMAGEWIDTH;
bi.biHeight = IMAGEHEIGHT;
bi.biPlanes = 1;
bi.biBitCount = 24;
bi.biCompression = 0;
bi.biSizeImage = WIDTHBYTES(bi.biWidth * bi.biBitCount) * bi.biHeight;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
//Set BITMAPFILEHEADER
bf.bfType = 0x4d42;
bf.bfSize = 54 + bi.biSizeImage;
bf.bfReserved1 = 0;
bf.bfReserved2 = 0;
bf.bfOffBits = 54;
buffer = malloc(bi.biSizeImage);
if (!buffer) {
printf("Out of memory.\n");
exit(1);
}
for(i=0; i<20; i++)
getVideoData(buffer, bi.biSizeImage);
fwrite(&bf, 14, 1, fp);
fwrite(&bi, 40, 1, fp);
fwrite(buffer, bi.biSizeImage, 1, fp);
printf("get bmp form video\t[OK]\n");
fclose(fp);
closeVideo();
return 0;
}
//------------------------------------------------------------------------------
网上摘录下来的,经过了调试修改.在gcc4.1 arm-linux-gcc-3.4.1 编译通过.
在s3c2410 pc上可以正常运行.