现在的位置: 首页 > 综合 > 正文

OK6410预览并实现截图操作(RGB565)

2013年12月02日 ⁄ 综合 ⁄ 共 4019字 ⁄ 字号 评论关闭

涉及内容:

1、v4l2操作摄像头

2、RGB565转BMP(RGB16)文件

参考代码:

#include <sys/time.h>
#include <sys/types.h>
#include <asm/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <errno.h>

#include <jpeglib.h>

#include <linux/fs.h>
#include <linux/kernel.h>
#include "videodev2.h"
#include <linux/fb.h>



#include "jpeglib.h"

#define CTRL_NUM 100

#define WIDTH               480
#define HEIGHT              272
//文件头
struct tagBITMAPFILEHEADER{

    unsigned long bfSize;
    unsigned long bfLeft;
    unsigned long bfOffBits;

};
// bmp图像的位图信息头
struct tagBITMAPINFOHEADER{
    unsigned long biSize;
    unsigned long bmpWidth;
    unsigned long bmpHeight;
    unsigned short biPlanes;
    unsigned short bicolors;
    unsigned long isCompressed;
    unsigned long biMapSize;
    unsigned long biHorizontal;
    unsigned long biVertical;
    unsigned long biusedcolors;
    unsigned long biimportcolors; 
};


#define V4L2_DEV_NODE "/dev/video1"
#define FB_DEV_NODE "/dev/fb0"


typedef struct v4l2_input    V_INPUT;
typedef struct v4l2_format   V_FORMAT;
typedef struct v4l2_fmtdesc  V_FMTDESC;
typedef struct v4l2_queryctrl V_QRYCTRL;

typedef struct fb_var_screeninfo F_VINFO;



#define V4L2_FMT_IN		0
#define V4L2_FMT_OUT		1


unsigned char *preview_buf;


static void writebmp(int data_fd){
	int i,j,k,size;
	int ret;

	unsigned char *buf1 = (unsigned char *)malloc(sizeof(unsigned char) * 480*272*2);
	memcpy(buf1, preview_buf, 480*272*2);

	unsigned short buf[WIDTH*HEIGHT]={0};
	printf("Write buf[i*WIDTH+k] begin!\n");
	for(i=0;i<HEIGHT;i++)
	{
    for(j=0;j<WIDTH;j++)
    {
			*(buf+i*WIDTH+j)= (buf1[i*WIDTH*2+j*2])|(buf1[i*WIDTH*2+j*2+1]<<8);
			//if(i<1)
			//	printf("(%d,%d,0x%4x)\n",i,j,*(buf+i*WIDTH+j));
		}
	}
	printf("Write buf[i*WIDTH+k] end!\n");
	unsigned short bmp[WIDTH*HEIGHT];
	    
	struct tagBITMAPFILEHEADER bfhead;
	struct tagBITMAPINFOHEADER binfohead;
	size=HEIGHT*WIDTH;
	
	
	bfhead.bfSize=0x36+size*2;
	bfhead.bfLeft=0;
	bfhead.bfOffBits=0x36;
	
	binfohead.biSize=0x28;
	binfohead.bmpWidth=WIDTH;
	binfohead.bmpHeight=HEIGHT;
	binfohead.biPlanes=1;
	binfohead.bicolors=0x10;
	binfohead.isCompressed=0;
	binfohead.biMapSize=size*2;
	binfohead.biHorizontal=0x0b13;
	binfohead.biVertical=0x0b13;
	binfohead.biusedcolors=0;
	binfohead.biimportcolors=0;
	
	for(i=0;i<HEIGHT;i++)
		for(j=0;j<WIDTH;j++)
	    	*(bmp+i*WIDTH+j)=((buf[(HEIGHT-i)*WIDTH-WIDTH+j]&0xf800)>>1)|((buf[(HEIGHT-i)*WIDTH-WIDTH+j]&0x07c0)>>1)|((buf[(HEIGHT-i)*WIDTH-WIDTH+j]&0x1f));
	//翻转图像 	
	//for (i=HEIGHT; i>=0;i--)
	//	for(j=WIDTH;j>=0;j--)
	//		*(bmp+i*WIDTH+j)=((buf[i*WIDTH+j]&0xf800)>>1)|((buf[i*WIDTH+j]&0x07c0)>>1)|((buf[i*WIDTH+j]&0x1f));
			
	write(data_fd,"BM",2);
	i=write(data_fd,&bfhead,sizeof(struct tagBITMAPFILEHEADER));
	printf("Write filehead %dbytes\n",i);
	
	i=write(data_fd,&binfohead,sizeof(struct tagBITMAPINFOHEADER));
	printf("Write infohead %dbytes\n",i);
	i=write(data_fd,bmp,size*2);
	printf("Write bitmap %dbytes\n",i);
	
	lseek(data_fd,SEEK_SET,4);
}


int main(void)
{
	int v4l2_fd = -1;
	int fb_fd = -1;
	int n=0;
	__u8 *fb_buf;
	__u32 screensize;
	V_FORMAT fmt;
	struct v4l2_capability caminfo;
	
	v4l2_fd = open(V4L2_DEV_NODE, O_RDWR);
	if (v4l2_fd < 0) {
		printf(" open video ERR\n");
	}

	fb_fd = open(FB_DEV_NODE, O_RDWR);
	if (fb_fd < 0) {
		printf(" open FB ERR\n");
	}
	
	screensize = 480 * 272 * 16 / 8;
	fb_buf = (__u8 *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
				fb_fd, 0);
	if ((int)fb_buf == -1) {
		printf("Error: failed to map framebuffer device to memory.\n");
		close(fb_fd);
		return -1;
	}

	if((n =(ioctl(v4l2_fd, VIDIOC_QUERYCAP, &caminfo)))<0)
	 	printf("Error: failed to get camera info.%d\n",n);
	 //设置图象模式
 	fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

	fmt.fmt.pix.width = 480;
	fmt.fmt.pix.height = 272;

	fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB565;
	fmt.fmt.pix.priv = V4L2_FMT_OUT;		
	if((ioctl(v4l2_fd, VIDIOC_S_FMT, &fmt))<0)
		printf("Error: failed to set video format.\n");

	int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	if((ioctl(v4l2_fd, VIDIOC_STREAMON, &type))<0)
		printf("start to get pic %d\n",(int)fmt.fmt.pix.sizeimage);

	int ii = 0;
	while(1){
		n=read(v4l2_fd, fb_buf, 480*272*2);
		if (ii == 0 && n > 0) {
			int data_fd=-1;
			
			printf("read Data Length:%d\n", n);
			preview_buf =  malloc(n);
			memcpy(preview_buf, fb_buf, n);
			
			
			char bmpfilename[30];
			sprintf(bmpfilename, "/sdcard/photo%d.bmp",1);
			
			if((data_fd = open(bmpfilename,O_CREAT|O_RDWR,0777))<0){
				printf("Error: failed to creat photo.bmp.\n");
				return 0;
			}
			printf("bmpfilename is %s\n",bmpfilename);

			writebmp(data_fd);
			if(data_fd>0)
                		close(data_fd);
			free(preview_buf);
	    ii = 1;
  	}
	}

}

抱歉!评论已关闭.