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


    涉及内容:

    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;
      	}
    	}
    
    }
    

  • 相关阅读:
    安装、设置与启动MySql5.1.30绿色版的方法
    可执行jar包的maven配置
    Maven配置文件说明
    Maven常用命令
    eclipse下创建maven工程
    [Linux]常用命令与目录全拼
    Linux的端口和服务
    TortoiseSVN
    SpringCloud-断路器(Hystrix)
    SpringCloud-服务的消费者(Feign)
  • 原文地址:https://www.cnblogs.com/whisht/p/3085073.html
Copyright © 2020-2023  润新知