linux 下修剪图片_linux sed修剪字符串 - CSDN
  • 关于Linux下的视频采集编程 一.什么是video4linux Video4linux2(简称V4L2),是linux中关于视频设备的内核驱动。在Linux中,视频设备是设备文件,可以像访问普通文件一样对其进行读写,摄像头在/dev/video0。 二...

    关于Linux下的视频采集编程

    一.什么是video4linux
    Video4linux2(简称V4L2),linux中关于视频设备的内核驱动。在Linux中,视频设备是设备文件,可以像访问普通文件一样对其进行读写,摄像头在/dev/video0下。

    二、一般操作流程(视频设备):
    1.打开设备文件 int fd=open(”/dev/video0″,O_RDWR);
    2.
    取得设备的capability,看看设备具有什么功能,比如是否具有视频输入,或者音频输入输出等。VIDIOC_QUERYCAP,struct v4l2_capability
    3.
    选择视频输入,一个视频设备可以有多个视频输入。VIDIOC_S_INPUT,struct v4l2_input
    4.
    设置视频的制式和帧格式,制式包括PALNTSC,帧的格式个包括宽度和高度等。
    VIDIOC_S_STD,VIDIOC_S_FMT,structv4l2_std_id,struct v4l2_format
    5.
    向驱动申请帧缓冲,一般不超过5个。structv4l2_requestbuffers
    6.
    将申请到的帧缓冲映射到用户空间,这样就可以直接操作采集到的帧了,而不必去复制。mmap
    7.
    将申请到的帧缓冲全部入队列,以便存放采集到的数据.VIDIOC_QBUF,struct v4l2_buffer
    8.
    开始视频的采集VIDIOC_STREAMON
    9.
    出队列以取得已采集数据的帧缓冲,取得原始采集数据VIDIOC_DQBUF
    10.
    将缓冲重新入队列尾,这样可以循环采集VIDIOC_QBUF
    11.
    停止视频的采集VIDIOC_STREAMOFF
    12.
    关闭视频设备close(fd);

     

    三、常用的结构体(参见/usr/include/linux/videodev2.h)
    struct v4l2_requestbuffers reqbufs;//向驱动申请帧缓冲的请求,里面包含申请的个数
    struct v4l2_capability cap;//
    这个设备的功能,比如是否是视频输入设备
    struct v4l2_input input; //
    视频输入
    struct v4l2_standard std;//视频的制式,比如PALNTSC
    struct v4l2_format fmt;//帧的格式,比如宽度,高度等
    struct v4l2_buffer buf;//代表驱动中的一帧
    v4l2_std_id stdid;//视频制式,例如:V4L2_STD_PAL_B
    struct v4l2_queryctrl query;//
    查询的控制
    struct v4l2_control control;//具体控制的值

     

    四、下面具体说明开发流程
    1.打开视频设备
    V4L2中,视频设备被看做一个文件。使用open函数打开这个设备:
    //
    用非阻塞模式打开摄像头设备
    int cameraFd;
    cameraFd =
    open(“/dev/video0″, O_RDWR | O_NONBLOCK, 0);

    //
    如果用阻塞模式打开摄像头设备,上述代码变为:
    //cameraFd = open(”/dev/video0″, O_RDWR, 0);

    关于阻塞模式和非阻塞模式
    应用程序能够使用阻塞模式或非阻塞模式打开视频设备,如果使用非阻塞模式调用视频设备,即使尚未捕获到信息,驱动依旧会把缓存(DQBUFF)里的东西返回给应用程序。

    2.设定属性及采集方式
    打开视频设备后,可以设置该视频设备的属性,例如裁剪、缩放等。这一步是可选的。在Linux编程中,一般使用ioctl函数来对设备的I/O通道进行管理:
    extern int
    ioctl (int __fd, unsigned long int __request, …) __THROW;

    __fd:设备的ID,例如刚才用open函数打开视频通道后返回的cameraFd
    __request
    :具体的命令标志符。

    在进行V4L2开发中,一般会用到以下的命令标志符:
    VIDIOC_REQBUFS:分配内存

    VIDIOC_QUERYBUF:把VIDIOC_REQBUFS中分配的数据缓存转换成物理地址
    VIDIOC_QUERYCAP
    :查询驱动功能
    VIDIOC_ENUM_FMT:获取当前驱动支持的视频格式
    VIDIOC_S_FMT:设置当前驱动的视频捕获格式
    VIDIOC_G_FMT
    :读取当前驱动的频捕获格式
    VIDIOC_TRY_FMT
    :验证当前驱动的显示格式
    VIDIOC_CROPCAP
    :查询驱动的修剪能力
    VIDIOC_S_CROP
    :设置视频信号的边框
    VIDIOC_G_CROP
    :读取视频信号的边框
    VIDIOC_QBUF:把数据从缓存中读取出来
    VIDIOC_DQBUF
    :把数据放回缓存队列
    VIDIOC_STREAMON:开始视频显示函数
    VIDIOC_STREAMOFF:结束视频显示函数
    VIDIOC_QUERYSTD
    :检查当前视频设备支持的标准,例如PALNTSC
    这些IO调用,有些是必须的,有些是可选择的。

    检查当前视频设备支持的标准:
    在亚洲,一般使用PAL720X576)制式的摄像头,而欧洲一般使用NTSC720X480),使用VIDIOC_QUERYSTD来检测:

    v4l2_std_id std;

    do {
        ret = ioctl(fd, VIDIOC_QUERYSTD, &std);
    } while (ret == -1 && errno == EAGAIN);

    switch (std) {
        case V4L2_STD_NTSC:
            //……
        case V4L2_STD_PAL:
            //……
    }

    3.设置视频捕获格式

    当检测完视频设备支持的标准后,还需要设定视频捕获格式:

    struct v4l2_format    fmt;
    memset ( &fmt, 0, sizeof(fmt) );
    fmt.type               = V4L2_BUF_TYPE_VIDEO_CAPTURE;  //
    类型
    fmt.fmt.pix.width      = 720;    //

    fmt.fmt.pix.height     = 576;    //

    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;   //
    像素格式
    fmt.fmt.pix.field      = V4L2_FIELD_INTERLACED;  //
    图片区域

    if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1)    //
    设置当前驱动的频捕获格式

    {

      return -1;

    }


    v4l2_format结构体定义如下

    struct v4l2_format
    {

        enum v4l2_buf_typetype;   // 数据流类型,必须永远是V4L2_BUF_TYPE_VIDEO_CAPTURE  

        union

        {

            structv4l2_pix_format    pix;

            structv4l2_window        win;

            structv4l2_vbi_format    vbi;

           __u8    raw_data[200];        

         } fmt;

    };

    struct v4l2_pix_format
    {

       __u32                  width;         //宽,必须是16的倍数

       __u32                  height;        //高,必须是16的倍数

       __u32                  pixelformat;   //视频数据存储类型,例如是//YUV422还是RGB

          enumv4l2_field         field;

       __u32                  bytesperline;   

       __u32                  sizeimage;

          enum v4l2_colorspace   colorspace;

       __u32                  priv;      

    };

    4.分配内存

    接下来可以为视频捕获分配内存:

    struct v4l2_requestbuffers  req;
    if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1)

    {

          return -1;
    }

    v4l2_requestbuffers
    定义如下:

    struct v4l2_requestbuffers

    {

       __u32       count;  // 缓存数量,也就是说在缓存队列里保持多少张照片

         enumv4l2_buf_type  type;         

         // 数据流类型,必须永远是V4L2_BUF_TYPE_VIDEO_CAPTURE

     

         enum v4l2_memory    memory;

         // V4L2_MEMORY_MMAP V4L2_MEMORY_USERPTR

         __u32              reserved[2];
    };

     

    5.获取并记录缓存的物理空间

    使用VIDIOC_REQBUFS,我们获取了req.count个缓存,下一步通过调用VIDIOC_QUERYBUF命令来获取这些缓存的地址,然后使用mmap函数转换成应用程序中的绝对地址,最后把这段缓存放入缓存队列:


    <!--[if !supportLineBreakNewLine]-->
    <!--[endif]-->

    typedef struct VideoBuffer

    {

          void   *start;

         size_t  length;

    } VideoBuffer;

     

    VideoBuffer*         buffers = calloc( req.count, sizeof(*buffers) );

    struct v4l2_buffer    buf;

     

    for (numBufs = 0; numBufs < req.count;numBufs++)

    {

         memset( &buf, 0, sizeof(buf) );

         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

         buf.memory = V4L2_MEMORY_MMAP;

         buf.index = numBufs;

         //读取缓存

         if (ioctl(fd, VIDIOC_QUERYBUF, &buf)== -1)

         {

              return -1;

         }

     

         buffers[numBufs].length =buf.length;

     

        //转换成相对地址

        buffers[numBufs].start = mmap(NULL,buf.length,

        PROT_READ | PROT_WRITE, MAP_SHARED, fd,buf.m.offset);

        if (buffers[numBufs].start == MAP_FAILED)

         {

            return -1;

         }

     

        // 放入缓存队列

        if (ioctl(fd, VIDIOC_QBUF, &buf) == -1)

       {

             return -1;

        }

    }

    6.关于视频采集方式

    操作系统一般把系统使用的内存划分成用户空间和内核空间,分别由应用程序管理和操作系统管理。应用程序可以直接访问内存的地址,而内核空间存放的是供内核访问的代码和数据,用户不能直接访问。v4l2捕获的数据,最初是存放在内核空间的,这意味着用户不能直接访问该段内存,必须通过某些手段来转换地址。

    一共有三种视频采集方式:使用readwrite方式;内存映射方式和用户指针模式。
    read
    write方式:在用户空间和内核空间不断拷贝数据,占用了大量用户内存空间,效率不高。
    内存映射方式:把设备里的内存映射到应用程序中的内存控件,直接处理设备内存,这是一种有效的方式。上面的mmap函数就是使用这种方式。

    用户指针模式:内存片段由应用程序自己分配。这点需要在v4l2_requestbuffers里将memory字段设置成V4L2_MEMORY_USERPTR

    处理采集数据

    V4L2
    有一个数据缓存,存放req.count数量的缓存数据。数据缓存采用FIFO的方式,当应用程序调用缓存数据时,缓存队列将最先采集到的视频数据缓存送出,并重新采集一张视频数据。这个过程需要用到两个ioctl命令,VIDIOC_DQBUFVIDIOC_QBUF

    struct v4l2_buffer buf;
    memset(&buf,0,sizeof(buf));
    buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
    buf.memory=V4L2_MEMORY_MMAP;
    buf.index=0;

    //读取缓存
    if (ioctl(cameraFd, VIDIOC_DQBUF, &buf) ==-1)
    {

    return -1;
    }

    //…………视频处理算法

    //
    重新放入缓存队列
    if (ioctl(cameraFd, VIDIOC_QBUF, &buf) ==-1)

    {

         return -1;
    }

    关闭视频设备

    使用close函数关闭一个视频设备

    close(cameraFd)

    还需要使用munmap方法。


    具体事例代码可参见本专栏资料实例





    展开全文
  • 我们都知道,想要驱动linux下的摄像头,其实很简单,照着V4L2的手册一步步来写,很快就可以写出来,但是在写之前我们要注意改变系统的一些配置,使系统支持framebuffer,在dev产生fb0这样的节点,这样我们才能在...

    我们都知道,想要驱动linux下的摄像头,其实很简单,照着V4L2的手册一步步来写,很快就可以写出来,但是在写之前我们要注意改变系统的一些配置,使系统支持framebuffer,在dev下产生fb0这样的节点,这样我们才能在linux系统上操作Camera摄像头,framebuffer在之前的博文已经有说过了,这里就不再提了。

    有需要了解framebuffer的那么请点击:http://baike.baidu.com/view/3351639.htm

           最重要的,我们需要改一个脚本,在/dev/grub.conf,我们来看看怎么改:

    # grub.conf generated by anaconda
    #
    # Note that you do not have to rerun grub after making changes to this file
    # NOTICE:  You have a /boot partition.  This means that
    #          all kernel and initrd paths are relative to /boot/, eg.
    #          root (hd0,0)
    #          kernel /vmlinuz-version ro root=/dev/sdb2
    #          initrd /initrd-[generic-]version.img
    #boot=/dev/sdb
    default=0
    timeout=5
    splashimage=(hd0,0)/grub/splash.xpm.gz
    hiddenmenu
    title CentOS (2.6.32-431.el6.i686)
    	root (hd0,0)
    	kernel /vmlinuz-2.6.32-431.el6.i686 ro root=UUID=2bc12537-d6c1-4e67-b4e5-e9c466205554 nomodeset rd_NO_LUKS  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_MD crashkernel=auto LANG=zh_CN.UTF-8 rd_NO_LVM rd_NO_DM rhgb quiet vga=0x318
    	initrd /initramfs-2.6.32-431.el6.i686.img
    

    通常情况下,要让framebuffer生效,要加一句vga=???(这里是参数),简单介绍一下:

    我写vga=0x318就是默认就设置为1024x768x24bpp模式。当然还有其它的模式:如下图,根据自己的系统来配置。
    色彩 640x400 640x480 800x600 1024x768 1280x1024 1600x1200
    4bits ? ? 0x302 ? ? ?
    8bits 0x300 0x301 0x303 0x305 0x307 0x31C
    15bits ? 0x310 0x313 0x316 0x319 0x31D
    16bits ? 0x311 0x314 0x317 0x31A 0x31E
    24bits ? 0x312 0x315 0x318 0x31B 0x31F
    32bits ? ? ? ? ? ?
    配置完成以后,我们先来了解一下V4L2的主要功能。
    V4L2就使程序有发现设备和操作设备的能力.它主要是用一系列的回调函数来实现这些功能。像设置摄像头的频率、帧频、视频压缩格式和图像参数等等。当然也可以用于其他多媒体的开发,如音频等。
    但是此框架只能运行在Linux操作系统之上。v4L2是针对uvc免驱usb设备的编程框架 ,主要用于采集usb摄像头等,编程模式如下:

    采集方式

    打开视频设备后,可以设置该视频设备的属性,例如裁剪、缩放等。这一步是可选的。在Linux编程中,一般使用ioctl函数来对设备的I/O通道进行管理:
    extern int ioctl (int __fd, unsigned long int __request, …) __THROW;
    __fd:设备的ID,例如刚才用open函数打开视频通道后返回的cameraFd;
    __request:具体的命令标志符。
    在进行V4L2开发中,一般会用到以下的命令标志符:
    VIDIOC_REQBUFS:分配内存
    VIDIOC_QUERYBUF:把VIDIOC_REQBUFS中分配的数据缓存转换成物理地址
    VIDIOC_QUERYCAP:查询驱动功能
    VIDIOC_ENUM_FMT:获取当前驱动支持的视频格式
    VIDIOC_S_FMT:设置当前驱动的频捕获格式
    VIDIOC_G_FMT:读取当前驱动的频捕获格式
    VIDIOC_TRY_FMT:验证当前驱动的显示格式
    VIDIOC_CROPCAP:查询驱动的修剪能力
    VIDIOC_S_CROP:设置视频信号的边框
    VIDIOC_G_CROP:读取视频信号的边框
    VIDIOC_QBUF:把数据放回缓存队列
    VIDIOC_DQBUF:把数据从缓存中读取出来
    VIDIOC_STREAMON:开始视频显示函数
    VIDIOC_STREAMOFF:结束视频显示函数
    VIDIOC_QUERYSTD:检查当前视频设备支持的标准,例如PAL或NTSC。
    这些IO调用,有些是必须的,有些是可选择的。

    V4L2操作流程:点击这个网址,说得很详细了,这里不多说。

    http://baike.baidu.com/view/5494174.htm

    接下来我们来看看实战部分,下面是我自己写的程序接口,可以实现视频采集:生气
    1、project.c
    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include "j-yuv.h"
    #include "CameralOpt.h"
    #include "FrameBufferOpt.h"
    
    #define    WIDTH   640
    #define    HIGHT   480
    
    int main(void)
    {
    	char yuyv[WIDTH*HIGHT*2];
    	char bmp[WIDTH*HIGHT*3];
    
    //	set_bmp_header((struct bmp_header_t *)bmp, WIDTH, HIGHT);
    	//初始化摄像头
    	Init_Cameral(WIDTH , HIGHT );
    	//初始化framebuffer
    	Init_FrameBuffer(WIDTH , HIGHT ); 
    
    	//开启摄像头
    	Start_Cameral();
    	//采集一张图片
    	int count = 0 ; 
    	while(1)
    	{
    		Get_Picture(yuyv);
    		yuyv2rgb24(yuyv, bmp, WIDTH, HIGHT);
    		Write_FrameBuffer(bmp);
    //		printf("count:%d \n" , count++);
    	}
    	//关闭摄像头
    	Stop_Cameral();
    	//关闭Framebuffer
    	Exit_Framebuffer();
    	//退出
    	Exit_Cameral();
    	
    	return 0;
    }
    
    
    2、juv.h
    #ifndef __JYUV_H
    #define __JYUV_H
    
    typedef unsigned char  u8;
    typedef unsigned short u16;
    typedef unsigned int   u32;
    
    #pragma pack(1)
    //定义bmp头
    struct bmp_header_t{
        u16        magic;
        u32       file_size;
        u32       RESERVED1;
        u32       offset;         //54 bytes 表示54个偏移量
    
        u32       head_num;    //40
        u32       width;
        u32       height;
        u16       color_planes; //1
        u16       bit_count;
        u32       bit_compression; //0
        u32       image_size; //except the size of header
        u32       h_resolution;
        u32       v_resolution;
        u32       color_num;
        u32       important_colors;
    };
    
    #pragma pack()
    
    void set_bmp_header(struct bmp_header_t * header, u32 width, u32 height);
    int yuyv2rgb24(u8 *yuyv, u8 *rgb, u32 width, u32 height);
    
    #endif /* __JYUV_H */ 
    3、juv.c
    #include "j-yuv.h"
    
    #define BIT_COUNT   24
    
    void set_bmp_header(struct bmp_header_t *header, u32 width, u32 height)
    {
        header->magic = 0x4d42;
        header->image_size = width * height * BIT_COUNT/8;
        header->file_size = header->image_size + 54;
        header->RESERVED1 = 0;
        header->offset = 54;
    
        header->head_num = 40;
        header->width = width;
        header->height = height;
        header->color_planes = 1;
        header->bit_count = BIT_COUNT;
        header->bit_compression = 0;
        header->h_resolution = 0;
        header->v_resolution = 0;
        header->color_num = 0;
        header->important_colors = 0;
    }
    //yuyv转rgb24的算法实现
    int yuyv2rgb24(u8 *yuyv, u8 *rgb, u32 width, u32 height)
    {
        u32 i, in, rgb_index = 0;
        u8 y0, u0, y1, v1;
        int r, g, b;
        u32 out = 0, x, y;
     
        for(in = 0; in < width * height * 2; in += 4)
        {
    	y0 = yuyv[in+0];
    	u0 = yuyv[in+1];
    	y1 = yuyv[in+2];
    	v1 = yuyv[in+3];
    
    	for (i = 0; i < 2; i++)
    	{
    		if (i)
    			y = y1;
    		else
    			y = y0;	
    		r = y + (140 * (v1-128))/100;  //r
    		g = y - (34 * (u0-128))/100 - (71 * (v1-128))/100; //g
     		b = y + (177 * (u0-128))/100; //b
    		if(r > 255)   r = 255;
            	if(g > 255)   g = 255;
            	if(b > 255)   b = 255;
           		if(r < 0)     r = 0;
            	if(g < 0)     g = 0;
    	        if(b < 0)     b = 0;
    
    		y = height - rgb_index/width -1;
    		x = rgb_index%width;
    		rgb[(y*width+x)*3+0] = b;
    		rgb[(y*width+x)*3+1] = g;
    		rgb[(y*width+x)*3+2] = r;
    		rgb_index++;
    	}
        }
        return 0;
    }
    
    
    4、FrameBufferOpt.c
    #include "FrameBufferOpt.h"
    
    static int Frame_fd ; 
    static int *FrameBuffer = NULL ; 
    static int W , H ;
    
    //初始化framebuffer
    int Init_FrameBuffer(int Width , int Higth)
    {
    	W = Width ; 
    	H = Higth ; 
    	Frame_fd = open("/dev/fb" , O_RDWR);
    	if(-1 == Frame_fd)
    	{
    		perror("open frame buffer fail");
    		return -1 ; 
    	}
    
    //根本就不用CPU搬运   用DMA做为搬运工
    FrameBuffer = mmap(0, 1280*1024*4 , PROT_READ | PROT_WRITE , MAP_SHARED , Frame_fd ,0 );
    	if(FrameBuffer == (void *)-1)
    	{
    		perror("memory map fail");
    		return -2 ;
    	}
    	return 0 ; 
    }
    
    //写入framebuffer
    int Write_FrameBuffer(const char *buffer)
    {
    	int row  , col ; 
    	char *p = NULL ; 
    	for(row = 0 ; row <1024 ; row++)
    	{
    		for(col = 0 ; col < 1280 ;  col++)
    		{
    			if((row < H)  && (col < W))
    			{
    				p = (char *)(buffer + (row * W+ col ) * 3); 
    				FrameBuffer[row*1280+col] = RGB((unsigned char)(*(p+2)),(unsigned char)(*(p+1)),(unsigned char )(*p));
    			}
    		}
    	}
    	return 0 ; 
    }
    
    //退出framebuffer
    int Exit_Framebuffer(void)
    {
    	munmap(FrameBuffer ,  W*H*4);
    	close(Frame_fd);
    	return 0 ; 
    }
    
    
    5、FrameBufferOpt.h
    #ifndef  _FRAMEBUFFEROPT_H
    #define  _FRAMEBUFFEROPT_H
    
    #include <stdio.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <sys/mman.h>
    
    
    #define    RGB(r,g,b)		((r<<16)|(g<<8)|b)
    
    //初始化ramebuffer
    int Init_FrameBuffer(int Width , int Higth);
    
    //写数据到framebuffer
    int Write_FrameBuffer(const char *buffer);
    
    //退出framebuffer
    int Exit_Framebuffer(void);
    
    
    
    #endif //_FRAMEBUFFEROPT_H
    
    6、CameralOpt.h
    #ifndef  _CAMERALOPT_H
    #define  _CAMERALOPT_H
    
    #include <stdio.h>
    #include <linux/videodev2.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <string.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <sys/mman.h>
    
    #define   COUNT  3
    //初始化摄像头
    int Init_Cameral(int Width , int Hight);
    int Exit_Cameral(void); //退出摄像头
    //摄像头开始采集
    int Start_Cameral(void);
    int Stop_Cameral(void);//停止摄像头
    //获取摄像头的数据
    int Get_Picture(char *buffer);
    
    #endif  //_CAMERALOPT_H
    
    7、CameralOpt.c
    #include "CameralOpt.h"
    int video_fd ; 
    int length ; 
    char *yuv[COUNT] ; 
    struct v4l2_buffer  enqueue  , dequeue ;  //定义出入队的操作结构体成员
    
    int Init_Cameral(int Width , int Hight)
    {
    	//参数检查
    	char *videodevname = NULL ; 
    	videodevname = "/dev/video0" ; 
    	
    	//打开设备
    	video_fd = open(videodevname , O_RDWR);
    	if(-1 == video_fd )
    	{
    		perror("open video device fail");
    		return -1 ; 
    	}
    
    	int i ; 
    	int ret ; 
    	struct v4l2_format  format ; 
    	format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE ; 
    	format.fmt.pix.width  = Width; 
    	format.fmt.pix.height = Hight; 
    	format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV ;  //我支持的格式是这个
    
    	ret = ioctl(video_fd , VIDIOC_S_FMT , &format);
    	if(ret != 0)
    	{
    		perror("set video format fail");
    		return -2 ; 
    	}
    
    
    	//申请buffer,切割成几个部分
    	//3
    	struct v4l2_requestbuffers  requestbuffer ; 
    	requestbuffer.count = COUNT ; 
    	requestbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE ; 
    	requestbuffer.memory = V4L2_MEMORY_MMAP ; 
    
    	ret = ioctl(video_fd , VIDIOC_REQBUFS , &requestbuffer);
    	if(ret != 0)
    	{
    		perror("request buffer fail ");
    		return -3  ;
    	}
    	
    	
    	//querybuffer
    	struct v4l2_buffer querybuffer ; 
    	querybuffer.type =  V4L2_BUF_TYPE_VIDEO_CAPTURE ; 
    	querybuffer.memory = V4L2_MEMORY_MMAP ; 
    
    	for(i = 0 ; i < COUNT ; i++)
    	{
    		querybuffer.index = i ; 	
    
    		ret = ioctl(video_fd , VIDIOC_QUERYBUF , &querybuffer);
    		if(ret != 0)
    		{
    			perror("query buffer fail");
    			return -4 ; 
    		}
    	
    //		printf("index:%d length:%d  offset:%d \n" , 
    //		querybuffer.index , querybuffer.length , querybuffer.m.offset);
    		length = querybuffer.length ; 
    
    		//将摄像头内存印射到进程的内存地址
    		yuv[i] = mmap(0,querybuffer.length , PROT_READ | PROT_WRITE , MAP_SHARED , video_fd , querybuffer.m.offset );
    
    
    		//列队
    		
    		struct v4l2_buffer  queuebuffer ; 
    		queuebuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE ; 
    		queuebuffer.memory =  V4L2_MEMORY_MMAP ; 
    		queuebuffer.index = i ; 	
    
    		ret = ioctl(video_fd , VIDIOC_QBUF , &queuebuffer);
    		if(ret != 0)
    		{
    			perror("queuebuffer fail");
    			return -5 ; 
    		}
    	}
    	//初始化入队出队
    	enqueue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE ; 
    	dequeue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE ; 
    	enqueue.memory = V4L2_MEMORY_MMAP ; 
    	dequeue.memory = V4L2_MEMORY_MMAP ; 
    
    	return 0 ; 
    }
    
    int Exit_Cameral(void)
    {
    	int i ; 
    	for(i = 0 ; i < COUNT ; i++)
    		munmap(yuv+i , length);
    	close(video_fd);
    	return 0 ; 
    }
    
    int Start_Cameral(void)
    {
    	//开启摄像头
    	int ret ; 
    	int on = 1 ; 
    	ret = ioctl(video_fd , VIDIOC_STREAMON , &on);
    	if(ret != 0)
    	{
    		perror("start Cameral fail");
    		return -1 ; 
    	}
    	return 0 ; 
    }
    int Stop_Cameral(void)
    {
    	//停止摄像头
    	int ret ; 
    	int off= 1 ; 
    	ret = ioctl(video_fd , VIDIOC_STREAMOFF, &off);
    	if(ret != 0)
    	{
    		perror("stop Cameral fail");
    		return -1 ; 
    	}
    	return 0 ;
    }
    
    int Get_Picture(char *buffer)
    {
    	int ret ; 
    	//出队
    	ret = ioctl(video_fd , VIDIOC_DQBUF , &dequeue);
    	if(ret != 0)
    	{
    		perror("dequeue fail");
    		return -1 ; 
    	}
    
    	//获取图片数据 YUV   yuv[dequeue.index]
    	memcpy(buffer , yuv[dequeue.index] , dequeue.length);
    //	write(yuyv_fd , yuv[dequeue.index] , dequeue.length);
    
    	enqueue.index = dequeue.index ; 
    	ret = ioctl(video_fd , VIDIOC_QBUF , &enqueue);
    	if(ret != 0)
    	{
    		perror("enqueue fail");
    		return -2 ; 
    	}
    	return 0 ; 
    }
    
    


    运行结果:楼主本人大笑大笑,长得丑别喷。大哭
    画面其实是一直在动的,只是我拍了一张图片而已。










    展开全文
  • 又到周五了,想着周末还是很嗨皮,于是晚上就去写了下linux实验报告。计科的报告从来离不开截图。想来最近应该有不少朋友要写linux报告,于是就来分享下linux截图的一点小心得。 Linux上截图是比较蛋疼的事情,...

    又到周五了,想着周末还是很嗨皮,于是晚上就去写了下linux实验报告。计科的报告从来离不开截图。想来最近应该有不少朋友要写linux报告,于是就来分享下linux截图的一点小心得。


    Linux上截图是比较蛋疼的事情,qq在linux不稳定易崩溃,webqq很卡,如果用普通键盘截图只好全屏截图以后还得拿图像工具修修剪剪,各种不爽啦。


    我知道的有两种方法:一种方法是用截图工具截图,这个大家可以网上搜下。因为本人用的是ubantu,自带有软件中心,但是安装总会出现问题,大家可以试试在终端敲入apt-get install +名称。下载安装,这个个人比较喜欢。如果有安装包的话,可以直接用dpki命令,我就不赘述了。

                                   第二种是我比较推荐的方法,打开系统设置(基于ubantu),在“键盘”菜单选择“快捷键”设置,之后会看到区域截图,然后大家就可以设置区域截图的热键了。这个方法比较简单,但是每次截图后又出现了一个问题,假如我有五个报告,每个报告需要截很多图,而ubantu区域截图保存默认是系统自带文件,且不会记忆你的选择,这样的话,如果我想把图片分类保存的话就需要每次重新选择路径,很麻烦。我自己闲着无聊就写了个shell小程序,解决了这个小问题。代码如下:

    #!/bin/sh

    read x

    cp ./图片/*.png  ./实验$x

    rm /图片/*.png

    echo "转移图片成功"


    利用这个shell程序,我们就不需要那么麻烦了,每次只需要保存在图片文件夹,然后运行程序,选择文件名即可。当然这个程序是很简单的,但是看出了shell的无比强大。难怪每个linux工程师都会shell编程了


    周末愉快!

    展开全文
  • 我们曾经在一篇短文中讨论过Linux 上最好的照片管理应用[1],Linux 上最好的代码编辑器[2]。今天我们将讨论Linux 上最好的视频编辑软件。 当谈到免费视频编辑软件,Windows Movie Maker 和 iMovie 是大部分人经常...

    我们曾经在一篇短文中讨论过 Linux 上最好的照片管理应用[1],Linux 上最好的代码编辑器[2]。今天我们将讨论 Linux 上最好的视频编辑软件。

    当谈到免费视频编辑软件,Windows Movie Maker 和 iMovie 是大部分人经常推荐的。

    很不幸,上述两者在 GNU/Linux 上都不可用。但是不必担心,我们为你汇集了一个最好的视频编辑器清单。

    Linux 上最好的视频编辑器

    接下来让我们一起看看这些最好的视频编辑软件。如果你觉得文章读起来太长,这里有一个快速摘要。

    < 如显示不全,请左右滑动 >

    视频编辑器 主要用途 类型
    Kdenlive 通用视频编辑 自由开源
    OpenShot 通用视频编辑 自由开源
    Shotcut 通用视频编辑 自由开源
    Flowblade 通用视频编辑 自由开源
    Lightworks 专业级视频编辑 免费增值
    Blender 专业级三维编辑 自由开源
    Cinelerra 通用视频编辑 自由开源
    DaVinci 专业级视频处理编辑 免费增值
    VidCutter 简单视频拆分合并 自由开源

    1、 Kdenlive

    Kdenlive - Ubuntu 上的免费视频编辑器

    Kdenlive[3]是 KDE[4]上的一个自由且开源[5]的视频编辑软件,支持双视频监控、多轨时间线、剪辑列表、自定义布局、基本效果,以及基本过渡效果。

    它支持多种文件格式和多种摄像机、相机,包括低分辨率摄像机(Raw 和 AVI DV 编辑)、mpeg2、mpeg4 和 h264 AVCHD(小型相机和便携式摄像机)、高分辨率摄像机文件(包括 HDV 和 AVCHD 摄像机)、专业摄像机(包括 XDCAM-HD™ 流、IMX™ (D10) 流、DVCAM (D10)、DVCAM、DVCPRO™、DVCPRO50™ 流以及 DNxHD™ 流)。

    如果你正寻找 Linux 上 iMovie 的替代品,Kdenlive 会是你最好的选择。

    Kdenlive 特性:

    ◈ 多轨视频编辑

    ◈ 多种音视频格式支持

    ◈ 可配置的界面和快捷方式

    ◈ 使用文本或图像轻松创建切片

    ◈ 丰富的效果和过渡

    ◈ 音频和视频示波器可确保镜头绝对平衡

    ◈ 代理编辑

    ◈ 自动保存

    ◈ 广泛的硬件支持

    ◈ 关键帧效果

    优点:

    ◈ 通用视频编辑器

    ◈ 对于那些熟悉视频编辑的人来说并不太复杂

    缺点:

    ◈ 如果你想找的是极致简单的编辑软件,它可能还是令你有些困惑

    ◈ KDE 应用程序以臃肿而臭名昭著

    安装 Kdenlive

    Kdenlive 适用于所有主要的 Linux 发行版。你只需在软件中心搜索即可。Kdenlive 网站的下载部分[6]提供了各种软件包。

    命令行爱好者可以通过在 Debian 和基于 Ubuntu 的 Linux 发行版中运行以下命令从终端安装它:

    1. sudo apt install kdenlive

    2、 OpenShot

    Openshot - ubuntu 上的免费视频编辑器

    OpenShot[7]是 Linux 上的另一个多用途视频编辑器。OpenShot 可以帮助你创建具有过渡和效果的视频。你还可以调整声音大小。当然,它支持大多数格式和编解码器。

    你还可以将视频导出至 DVD,上传至 YouTube、Vimeo、Xbox 360 以及许多常见的视频格式。OpenShot 比 Kdenlive 要简单一些。因此,如果你需要界面简单的视频编辑器,OpenShot 是一个不错的选择。

    它还有个简洁的开始使用 Openshot[8]文档。

    OpenShot 特性:

    ◈ 跨平台,可在 Linux、macOS 和 Windows 上使用

    ◈ 支持多种视频,音频和图像格式

    ◈ 强大的基于曲线的关键帧动画

    ◈ 桌面集成与拖放支持

    ◈ 不受限制的音视频轨道或图层

    ◈ 可剪辑调整大小、缩放、修剪、捕捉、旋转和剪切

    ◈ 视频转换可实时预览

    ◈ 合成,图像层叠和水印

    ◈ 标题模板,标题创建,子标题

    ◈ 利用图像序列支持2D动画

    ◈ 3D 动画标题和效果

    ◈ 支持保存为 SVG 格式以及矢量标题和可信证

    ◈ 滚动动态图片

    ◈ 帧精度(逐步浏览每一帧视频)

    ◈ 剪辑的时间映射和速度更改

    ◈ 音频混合和编辑

    ◈ 数字视频效果,包括亮度,伽玛,色调,灰度,色度键等

    优点:

    ◈ 用于一般视频编辑需求的通用视频编辑器

    ◈ 可在 Windows 和 macOS 以及 Linux 上使用

    缺点:

    ◈ 软件用起来可能很简单,但如果你对视频编辑非常陌生,那么肯定需要一个曲折学习的过程

    ◈ 你可能仍然没有达到专业级电影制作编辑软件的水准

    安装 OpenShot

    OpenShot 也可以在所有主流 Linux 发行版的软件仓库中使用。你只需在软件中心搜索即可。你也可以从官方页面[9]中获取它。

    在 Debian 和基于 Ubuntu 的 Linux 发行版中,我最喜欢运行以下命令来安装它:

    1. sudo apt install openshot

    3、 Shotcut

    Shotcut Linux 视频编辑器

    Shotcut[10]是 Linux 上的另一个编辑器,可以和 Kdenlive 与 OpenShot 归为同一联盟。虽然它确实与上面讨论的其他两个软件有类似的功能,但 Shotcut 更先进的地方是支持 4K 视频。

    支持许多音频、视频格式,过渡和效果是 Shotcut 的众多功能中的一部分。它也支持外部监视器。

    这里有一系列视频教程让你轻松上手 Shotcut[11]。它也可在 Windows 和 macOS 上使用,因此你也可以在其他操作系统上学习。

    Shotcut 特性:

    ◈ 跨平台,可在 Linux、macOS 和 Windows 上使用

    ◈ 支持各种视频,音频和图像格式

    ◈ 原生时间线编辑

    ◈ 混合并匹配项目中的分辨率和帧速率

    ◈ 音频滤波、混音和效果

    ◈ 视频转换和过滤

    ◈ 具有缩略图和波形的多轨时间轴

    ◈ 无限制撤消和重做播放列表编辑,包括历史记录视图

    ◈ 剪辑调整大小、缩放、修剪、捕捉、旋转和剪切

    ◈ 使用纹波选项修剪源剪辑播放器或时间轴

    ◈ 在额外系统显示/监视器上的外部监察

    ◈ 硬件支持

    你可以在这里[12]阅它的更多特性。

    优点:

    ◈ 用于常见视频编辑需求的通用视频编辑器

    ◈ 支持 4K 视频

    ◈ 可在 Windows,macOS 以及 Linux 上使用

    缺点:

    ◈ 功能太多降低了软件的易用性

    安装 Shotcut

    Shotcut 以 Snap[13]格式提供。你可以在 Ubuntu 软件中心找到它。对于其他发行版,你可以从此下载页面[14]获取可执行文件来安装。

    4、 Flowblade

    Flowblade ubuntu 上的视频编辑器

    Flowblade[15]是 Linux 上的一个多轨非线性视频编辑器。与上面讨论的一样,这也是一个自由开源的软件。它具有时尚和现代化的用户界面。

    用 Python 编写,它的设计初衷是快速且准确。Flowblade 专注于在 Linux 和其他自由平台上提供最佳体验。所以它没有在 Windows 和 OS X 上运行的版本。Linux 用户专享其实感觉也不错的。

    你也可以查看这个不错的文档[16]来帮助你使用它的所有功能。

    Flowblade 特性:

    ◈ 轻量级应用

    ◈ 为简单的任务提供简单的界面,如拆分、合并、覆盖等

    ◈ 大量的音视频效果和过滤器

    ◈ 支持 代理编辑[17]

    ◈ 支持拖拽

    ◈ 支持多种视频、音频和图像格式

    ◈ 批量渲染

    ◈ 水印

    ◈ 视频转换和过滤器

    ◈ 具有缩略图和波形的多轨时间轴

    你可以在 Flowblade 特性[18]里阅读关于它的更多信息。

    优点:

    ◈ 轻量

    ◈ 适用于通用视频编辑

    缺点:

    ◈ 不支持其他平台

    安装 Flowblade

    Flowblade 应当在所有主流 Linux 发行版的软件仓库中都可以找到。你可以从软件中心安装它。也可以在下载页面[19]查看更多信息。

    另外,你可以在 Ubuntu 和基于 Ubuntu 的系统中使用一下命令安装 Flowblade:

    1. sudo apt install flowblade

    5、 Lightworks

    Lightworks 运行在 ubuntu 16.04

    如果你在寻找一个具有更多特性的视频编辑器,这就是你想要的。Lightworks[20]是一个跨平台的专业视频编辑器,可以在 Linux、Mac OS X 以及 Windows上使用。

    它是一款屡获殊荣的专业非线性编辑[21](NLE)软件,支持高达 4K 的分辨率以及 SD 和 HD 格式的视频。

    Lightworks 可以在 Linux 上使用,然而它不开源。

    Lightwokrs 有两个版本:

    ◈ Lightworks 免费版

    ◈ Lightworks 专业版

    专业版有更多功能,比如支持更高的分辨率,支持 4K 和蓝光视频等。

    这个页面[22]有广泛的可用文档。你也可以参考 Lightworks 视频向导页[23]的视频。

    Lightworks 特性:

    ◈ 跨平台

    ◈ 简单直观的用户界面

    ◈ 简明的时间线编辑和修剪

    ◈ 实时可用的音频和视频FX

    ◈ 可用精彩的免版税音频和视频内容

    ◈ 适用于 4K 的 Lo-Res 代理工作流程

    ◈ 支持导出 YouTube/Vimeo,SD/HD视频,最高可达4K

    ◈ 支持拖拽

    ◈ 各种音频和视频效果和滤镜

    优点:

    ◈ 专业,功能丰富的视频编辑器

    缺点:

    ◈ 免费版有使用限制

    安装 Lightworks

    Lightworks 为 Debian 和基于 Ubuntu 的 Linux 提供了 DEB 安装包,为基于 Fedora 的 Linux 发行版提供了RPM 安装包。你可以在下载页面[24]找到安装包。

    6、 Blender

    Blender 运行在 Ubuntu 16.04

    Blender[25]是一个专业的,工业级的开源跨平台视频编辑器。它在制作 3D 作品的工具当中较为流行。Blender 已被用于制作多部好莱坞电影,包括蜘蛛侠系列。

    虽然最初设计用于制作 3D 模型,但它也具有多种格式视频的编辑功能。

    Blender 特性:

    ◈ 实时预览、亮度波形、色度矢量显示和直方图显示

    ◈ 音频混合、同步、擦洗和波形可视化

    ◈ 最多32个轨道,用于添加视频、图像、音频、场景、面具和效果

    ◈ 速度控制、调整图层、过渡、关键帧、过滤器等

    优点:

    ◈ 跨平台

    ◈ 专业级视频编辑

    缺点:

    ◈ 复杂

    ◈ 主要用于制作 3D 动画,不专门用于常规视频编辑

    安装 Blender

    7、 Cinelerra

    Cinelerra Linux 上的视频编辑器

    Cinelerra[28]从 1998 年发布以来,已被下载超过 500 万次。它是 2003 年第一个在 64 位系统上提供非线性编辑的视频编辑器。当时它是 Linux 用户的首选视频编辑器,但随后一些开发人员丢弃了此项目,它也随之失去了光彩。

    好消息是它正回到正轨并且良好地再次发展。

    如果你想了解关于 Cinelerra 项目是如何开始的,这里有些有趣的背景故事[29]。

    Cinelerra 特性:

    ◈ 非线性编辑

    ◈ 支持 HD 视频

    ◈ 内置框架渲染器

    ◈ 各种视频效果

    ◈ 不受限制的图层数量

    ◈ 拆分窗格编辑

    优点:

    ◈ 通用视频编辑器

    缺点:

    ◈ 不适用于新手

    ◈ 没有可用的安装包

    安装 Cinelerra

    你可以从 SourceForge[30]下载源码。更多相关信息请看下载页面[31]。

    8、 DaVinci Resolve

    DaVinci Resolve 视频编辑器

    如果你想要好莱坞级别的视频编辑器,那就用好莱坞正在使用的专业工具。来自 Blackmagic 公司的 DaVinci Resolve[32]就是专业人士用于编辑电影和电视节目的专业工具。

    DaVinci Resolve 不是常规的视频编辑器。它是一个成熟的编辑工具,在这一个应用程序中提供编辑,色彩校正和专业音频后期制作功能。

    DaVinci Resolve 不开源。类似于 LightWorks,它也为 Linux 提供一个免费版本。专业版售价是 $300。

    DaVinci Resolve 特性:

    ◈ 高性能播放引擎

    ◈ 支持所有类型的编辑类型,如覆盖、插入、波纹覆盖、替换、适合填充、末尾追加

    ◈ 高级修剪

    ◈ 音频叠加

    ◈ Multicam Editing 可实现实时编辑来自多个摄像机的镜头

    ◈ 过渡和过滤效果

    ◈ 速度效果

    ◈ 时间轴曲线编辑器

    ◈ VFX 的非线性编辑

    优点:

    ◈ 跨平台

    ◈ 专业级视频编辑器

    缺点:

    ◈ 不适用于通用视频编辑

    ◈ 不开源

    ◈ 免费版本中有些功能无法使用

    安装 DaVinci Resolve

    9、 VidCutter

    VidCutter Linux 上的视频编辑器

    不像这篇文章讨论的其他视频编辑器,VidCutter[33]非常简单。除了分割和合并视频之外,它没有其他太多功能。但有时你正好需要 VidCutter 提供的这些功能。

    VidCutter 特性:

    ◈ 适用于Linux、Windows 和 MacOS 的跨平台应用程序

    ◈ 支持绝大多数常见视频格式,例如:AVI、MP4、MPEG 1/2、WMV、MP3、MOV、3GP、FLV 等等

    ◈ 界面简单

    ◈ 修剪和合并视频,仅此而已

    优点:

    ◈ 跨平台

    ◈ 很适合做简单的视频分割和合并

    缺点:

    ◈ 不适合用于通用视频编辑

    ◈ 经常崩溃

    安装 VidCutter

    如果你使用的是基于 Ubuntu 的 Linux 发行版,你可以使用这个官方 PPA(LCTT 译注:PPA,个人软件包档案,PersonalPackageArchives):

    1. sudo add-apt-repository ppa:ozmartian/apps
    2. sudo apt-get update
    3. sudo apt-get install vidcutter

    Arch Linux 用户可以轻松的使用 AUR 安装它。对于其他 Linux 发行版的用户,你可以从这个 Github 页面[34]上查找安装文件。

    哪个是 Linux 上最好的视频编辑软件?

    文章里提到的一些视频编辑器使用 FFmpeg[35]。你也可以自己使用 FFmpeg。它只是一个命令行工具,所以我没有在上文的列表中提到,但一句也不提又不公平。

    如果你需要一个视频编辑器来简单的剪切和拼接视频,请使用 VidCutter。

    如果你需要的不止这些,OpenShot或者 Kdenlive是不错的选择。他们有规格标准的系统,适用于初学者。

    如果你拥有一台高端计算机并且需要高级功能,可以使用 Lightworks或者 DaVinci Resolve。如果你在寻找更高级的工具用于制作 3D 作品,你肯定会支持选择 Blender。

    这就是在 Ubuntu、Linux Mint、Elementary,以及其它发行版等 Linux 上最好的视频编辑软件的全部内容。向我们分享你最喜欢的视频编辑器。

     

    展开全文
  • Linux常用的英文总结

    2019-04-07 21:58:24
    1. file [fail] n。文件;诉 保存文件 2。命令[k ??mɑ:nd] n。命令,指令 3。使用[ju:z,ju:s] v。使用,用途 4。程序[?pr?ugr?m] n。程序 5。line [lain] n。(数据,程序)行,线路 ...设置,n...
  • 概要:这里介绍 Linux 上几个最好的视频编辑器,介绍它们的特性、利与弊,以及如何在你的 Linux 发行版上安装它们。 我们曾经在一篇短文中讨论过 Linux 上最好的照片管理应用[1],Linux 上最好的代码编辑器[2]。...
  • V4L2(Video4linux2),是linux中关于视频设备的内核驱动。在Linux中,我们可以像访问普通文件一样对视频设备进行操作,V4L2也为我们在用户空间操作视频设备提供了一系列接口,使得应用程序可以使用统一的AP...
  • Linux教程-修炼

    2020-03-24 16:19:20
    Linux第1章 Linux 简介1.1 为什么要学习Linux1.2 Linux是什么1.3 Linux 与 Unix的那些事\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kyomzZ8y-1581066058741)(media/9652c2dcd630b965...
  • linux视频采集X264编码

    2013-12-17 14:58:44
    #include "stdint.h" #include #include "x264.h" #include "x264_config.h" #include "stdio.h" /* SOCK ADD */ #include #include #include #include #include #include ...#define BUFFER_SIZ
  • V4L2 全称 Video for Linux Two API Specification,它是Linux 内核中关于视频设备的子系统,它为linux 的视频驱动提供了统一的接口,使得应用程序可以使用统一的API 函数操作不同的视频设备,极大地简化了视频...
  • 在ios中将一个正方形的图片裁剪成圆形的图片是一件非常容易的事情, 直接设置 imageView.layer.cornerRadius 这个属性, 再设置 imageView.clipsToBounds = YES 就可以了, 但是对于长方形的图片来说这个方式裁剪出来的...
  • JAVA实现对图片的剪切

    2015-05-26 16:00:14
    package com.erzhan.hibernate.Test; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream;...import java.io.IOExceptio
  • V4L2是linux操作系统用于采集图片、视频和音频数据的API接口,配合适当的视频采集设备和相应的驱动程序,可以实现图片、视频、音频等的采集。在远程会议、可视电话、视频监控系统和嵌入式多媒体终端中都有广泛的...
  • 学习如何使用 Linux® 命令行和一些基本的 Bash 脚本编写技巧,以便使用 ImageMagick 在图像上绘制线条和文本,并同时创建一个像素标尺。   有时,我需要在一张图像或一块空白画布上绘制几根线条和一些文本。就在...
  • Linux命令大全与Redis,RedisUtil工具类 Linux操作 1.基本操作 配置相关 nohup java -jar xxx.jar >/usr/local/temp.txt & 部署应用 su root 切换到管理员 ifconfig 查看网络设置 dhclient 让linux自动...
  • 一般操作流程(视频设备): 1.打开设备fd = open(FILE_VIDEO1, O_RDWR)) 2.取得设备的capability 看看设备具有什么功能 比如是否具有视频输入 或者音频输入输出等 VIDIOC QUERYCAP struct v4l2 capabilit 3 选择...
  • Linux命令行里的“瑞士军刀” 这里说的“瑞士军刀”是指那些简单的一句命令就能完成其它高级语言一大片代码才能完成的工作。 下面的这些内容是Quora网站上Joshua Levy网友的总结: ...
1 2 3 4 5 ... 20
收藏数 640
精华内容 256
关键字:

linux 下修剪图片