用ZC0301的芯片,在Linux环境下运行以下代码,希望用摄像头拍出并保存一张照片在硬盘里(PPM格式的),结果保存的图片打开后无任何信息。请问是哪里出错了?
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/mman.h>
#include<error.h>
#include<sys/ioctl.h>
#include<fcntl.h>
#include<sys/types.h>
#include<linux/videodev.h>
#define DEFAULT_DEVICE "/dev/video0"
#define VIDEO_MAXFRAME 2
typedef struct _V4L_struct
{
int fd;
struct video_capability capability;
struct video_buffer buffer;
struct video_picture picture;
struct video_tuner tuner;
struct video_mmap mmap;
struct video_mbuf mbuf;
unsigned char *map;
int frame_current;
int frame_using[VIDEO_MAXFRAME];
} v4l_device;
int v4l_get_capability(v4l_device *vd) // 获取摄像头的信息
{
if(ioctl(vd->fd,VIDIOCGCAP,&(vd->capability))<0)
{
perror("v4l_get_capability:");
return -1;
}
printf(" camera name:%s\n",vd->capability.name);
printf(" camera type:%d\n",vd->capability.type);
printf(" camera channel:%d\n",vd->capability.channels);
printf(" camera audiosz:%d\n",vd->capability.audios);
printf(" camera maxwidth:%d\n",vd->capability.maxwidth);
printf(" camera maxheight:%d\n",vd->capability.maxheight);
printf(" camera minwidth:%d\n",vd->capability.minwidth);
printf(" camera minheight:%d\n",vd->capability.minheight);
return 0;
}
int v4l_get_picture(v4l_device *vd) // 图片的信息/
{
if(ioctl(vd->fd,VIDIOCGPICT,&(vd->picture))<0)
{
perror("v4l_get_picture");
return -1;
}
printf(" brightness:%d\n",vd->picture.brightness);
printf(" hue:%d\n",vd->picture.hue);
printf(" color:%d\n",vd->picture.colour);
printf(" contrast:%d\n",vd->picture.contrast);
printf(" whiteness:%d\n",vd->picture.whiteness);
printf(" depth:%d\n",vd->picture.depth);
printf(" palette:%d\n",vd->picture.palette);
return 0;
}
int v4l_get_mbuf(v4l_device *vd)
{
if(ioctl(vd->fd,VIDIOCGMBUF,&(vd->mbuf))<0)
{
perror("v4l_get_mbuf:");
return -1;
}
printf("size=%d\n",vd->mbuf.size);
return 0;
}
int v4l_open(char *dev,v4l_device *vd)
{
if(!dev) dev=DEFAULT_DEVICE;
dev=DEFAULT_DEVICE;
if((vd->fd=open(dev,O_RDWR))<0)
{
perror("v4l_open :");
return -1;
}
if(v4l_get_capability(vd)) return -1;
if(v4l_get_picture(vd)) return -1;
return 0;
printf("摄像头打开成功!\n");
}
int v4l_mmap_init(v4l_device *vd)
{
if(v4l_get_mbuf(vd)<0)
return -1;
if((vd->map=mmap(0,vd->mbuf.size,PROT_READ | PROT_WRITE,MAP_SHARED,vd->fd,0))<0)
{
perror("v4l_mmap_init:mmap");
return -1;
}
printf("内存映射成功!\n");
return 0;
}
int v4l_grab_frame(v4l_device *vd,int frame)
{
if(vd->frame_using[frame])
{
fprintf(stderr,"v4l_grab_frame:frame %d is already used \n",frame);
return -1;
}
vd->mmap.frame=frame;
if(ioctl(vd->fd,VIDIOCMCAPTURE,&(vd->mmap))<0)
{
perror("v4l_grab_frame");
return -1;
}
vd->frame_using[frame]=1;
vd->frame_current=frame;
printf(" 图像抓取成功!\n");
return 0;
}
int v4l_grab_init(v4l_device *vd,int width,int height)
{
vd->mmap.width=width;
vd->mmap.height=height;
vd->mmap.format=vd->picture.palette;
vd->frame_current=0;
vd->frame_using[0]=0;
vd->frame_using[1]=0;
return v4l_grab_frame(vd,0);
}
int v4l_save_ppm( unsigned char *p,int x,int y,int depth)
{
FILE *fp;
if((fp=fopen("/mnt/hgfs/Linux-Windows/test.ppm","wb+"))==NULL)
{
perror("open");
return -1;
}
fprintf(fp,"P6\n%d%d\n255\n",x,y);
fwrite((unsigned char *)p,x*y*depth,1,fp);
fclose(fp);
printf("图像保存成功!\n");
return 0;
}
int main()
{
v4l_device vd;
v4l_open(DEFAULT_DEVICE,&vd);
v4l_mmap_init(&vd);
v4l_grab_init(&vd,320,240);
v4l_save_ppm(vd.map,320,240,24);
return 0;
}