zoukankan      html  css  js  c++  java
  • jpg图片在开发板上显示

    文件IO项目:
    在开发板屏幕上循环显示目录里的图片
    a.按照一定的间隔循环显示目录里的bmp图片
    b.实现手指滑动来显示目录里的图片(bmp,jpg)上一张,下一张


    d1:
    1.能操控屏幕(查询开发板屏幕分辨率,以及每个像素点占几个字节)
    命令:FBIOGET_VSCREENINFO
    查询结果保存在些结构中:
    struct fb_var_screeninfo fbinfo;
    __u32 xres; 屏幕分辨率
    __u32 yres;
    __u32 bits_per_pixel; 每个像素点占多少位 /* guess what */

    ioctl(fd,FBIOGET_VSCREENINFO,&fbinfo);
    1.control device
    控制设备

    int ioctl(int fd, int request, ...);
    fd:文件描述符,表示要操作的设备
    request:一般表示一个命令号,该命令由驱动开发者提供
    ...:其它参数,不同的命令参数是不一样的,也由驱动程序员提供

    返回值:返回0
    失败-1
    ------------------------------------------------
    2.功能:映射一个文件或设备到内存,实现像操作普通内存一样去操作文件或设备
    void *mmap(
    void *addr, 把文件内容映射到内存哪个地址,给NULL,让操作系统自动分配
    size_t length,要映射的文件内容的长度
    int prot, 映射的内存区域的权限
    PROT_EXEC 可执行
    PROT_READ 可读
    PROT_WRITE 可写
    int flags,映射标志,决定对映射部分的操作是否对其它进程可见
    MAP_SHARED:共享的,对其它进程可见,内存操作直接应用到文件中去
    MAP_PRIVATE:私有的,对其它进程不可见,内存操作不应用到文件中去

    int fd,文件描述符,要映射的文件
    off_t offset 偏移量,表示文件从哪个位置开始映射
    );

    返回值:成功返回映射内存区域的首地址
    失败返回 MAP_FAILED(-1),同时errno被设置


    int munmap(void *addr, size_t length);
    功能:解除映射
    addr:mmap的返回值
    length:映射内存的长度

    返回值:成功返回0
    失败返回-1




    void *memset(void *s, int c, size_t n);
    s:要设置的内存首地址
    c:要设置的内容
    n:长度

    //struct student s;
    //memset(&s,0,sizeof(s));
    //void *memcpy(void *dest, const void *src, size_t n);

    memcpy(addr,gImage_cat2,800*480*4);


    2.显示图片



    -----------------------------------------
    Linux Frame Buffer:
    帧缓冲设备:
    是对具体图像硬件的一个抽像,它让上层图像应用程序不必关心具体的硬件实现细节。
    在内存(显存)中开辟一段空间,用来保存在屏幕上像素点的颜色值,然后操作屏幕就直接操作这段内存就可以了,这就是说的帧缓冲。

    LCD显示原理:
    屏幕是由y行且每行x个像素点的矩阵组成
    在屏幕上显示图像就是给每个像素点显示一个颜色。

    帧缓冲设备操作流程:
    1.open打开设备
    2.ioctl获取屏幕信息
    3.mmap映射设备到内存
    4.操作显存
    5.munmap解除映射
    6.close关闭文件

    1.显示jpg图片
    libjpeg移植:
    1.解压
    tar xvf jpegsrc.v8a.tar.gz
    2.cd jpeg-8a/
    3.配置参数(生成Makefile)
    ./configure --host=arm-linux --target=arm-linux --prefix=/usr/local/libjpeg-8a CC=arm-linux-gcc
    (
    注:
    如果没有建立交叉编译工具软链接的同学请用这个
    CC=arm-none-linux-gnueabi-gcc
    )

    4.make
    5.sudo make install
    注:
    sudo make install时可能出现以下错误
    ./libtool: line 950: arm-linux-ranlib: command not found
    解决方法:
    sudo -s
    export PATH=$PATH:/usr/local/arm/arm-2009q3/bin
    重新执行以下命令
    make install

    6.把生成库文件打包下载到开发板
    cd /usr/local/libjpeg-8a
    tar zcvf libjpeg-8a.tar.gz lib/

    7.在开发板上解压刚下载的包
    tar xvf libjpeg-8a.tar.gz
    cd lib/
    cp libjpeg.* /lib/


    arm-linux-gcc test_jpeg.c -o test_jpeg2
    -ljpeg //指定链接的库名
    -I /usr/local/libjpeg-8a/include/ //指定头文件存放路径
    -L /usr/local/libjpeg-8a/lib/ //指定库文件存放路径



    -------------------------
    tftp用法:
    1.乌班图下启动服务

    sudo service tftpd-hpa restart
    [sudo] password for csgec:
    tftpd-hpa stop/waiting
    tftpd-hpa start/running, process 15716

    2.tftp -g -r filename 主机IP
    (timeout)
    如果超时,请检查网络是否畅通
    从主机ping开发板
    从开发板ping主机
    检查开发板和主机是否在同一网段
    如果是笔记本,把无线网卡先断开

    --------------------------------------
    输入事件:
    鼠标事件
    键盘事件
    触屏事件
    ...
    #include <linux/input.h>
    一般触屏分为是否按下,用压力值来区分,当压力值为0时表示没按下
    触屏事件使用的是绝对坐标(包括x和y)
    struct input_event {
    struct timeval time;//该事件发生的时间
    __u16 type;//事件类型
    EV_KEY 0x01 键盘事件
    EV_REL 0x02 鼠标事件
    EV_ABS 0x03 触摸事件

    __u16 code;//根据事件类型同,含义不同
    if type == EV_KEY
    code 为键盘的键值
    if type = EV_REL
    code 为坐标轴 REL_X REL_Y
    if type = EV_ABS
    code 为坐标轴 ABS_X ABS_Y ABS_PRESSURE(压力)
    __s32 value;//根据事件类型同,含义不同
    if type == EV_KEY
    value 1 / 0 表示按键up/down
    if type = EV_REL
    value表示相应的坐标轴的偏移
    if type = EV_ABS
    value表示相应的坐标轴的绝对坐标
    X:(1-800)
    Y:(1-480)
    压力值:200 或 0(表示没按下)

    };

    #define ABS_PRESSURE 0x18//表示压力值

    获取起点和终点
    起点:按下去就可获取
    终点:当压力值为0时,也就是松开时的那个坐标值
    终点-起点 > 50

    #include<stdio.h>
    #include<linux/input.h>
    #include<fcntl.h>

    int main(int argc,char **argv)
    {

    int fd = open("/dev/event0",O_RDONLY);
    if(fd < 0)
    {
    perror("open");
    return -1;
    }
    struct input_event ev;
    int r;
    while(1)
    {
    r = read(fd,&ev,sizeof(ev));
    if(r == sizeof(ev))
    {
    printf("type = %x,code = %x,value = %x ",ev.type,ev.code,ev.value);
    }
    /*
    if(ev.type == EV_ABS && ev.code == ABS_PRESSURE)
    {
    printf("value = %d ",ev.value);
    }

    if(ev.type == EV_ABS && ev.code == ABS_X)
    {

    printf("value = %d ",ev.value);

    }
    */

    }
    return 0;
    }

    /*************************************************************************
    > File Name: test_jpeg.c
    > Author: csgec
    > Mail: longer.zhou@gmail.com
    > Created Time: Thu 04 Aug 2016 10:57:30 AM CST
    ************************************************************************/

    #include<stdio.h>
    #include<jpeglib.h>
    #include<fcntl.h>
    #include<sys/mman.h>
    #include<stdlib.h>

    void lcdDraw_point(int *p,int x,int y,int color)
    {
    *(p + 800*y + x) = color;
    }

    int main(int argc,char ** argv)
    {
    //1
    int fb = open("/dev/fb0",O_RDWR);
    if(fb < 0)
    {
    perror("open");
    return -1;
    }

    //2
    void *addr = mmap(0,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);
    if(addr == MAP_FAILED)
    {
    perror("mmap");
    return -1;
    }

    //-----------利用libjpeg解压jpeg文件的步骤--------------------------------
    //1.分配并初始化一个jpeg解压对象
    printf("start jpeg ");
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_decompress(&cinfo);

    //2.指定要解压的文件
    FILE *infile;
    infile = fopen(argv[1],"r");
    if(infile == NULL)
    {
    fprintf(stderr, "can't open %s ", argv[1]);
    return -1;
    }
    jpeg_stdio_src(&cinfo, infile);

    //3.获取图片信息
    jpeg_read_header(&cinfo, TRUE);

    //4.启动解压过程,cinfo中下面几个成员会比较有用
    //cinfo.output_width 宽_
    //cinfo.output_height 高
    //cinfo.output_components 像素分量(一个像素点占几个字节)
    //cinfo.
    jpeg_start_decompress(&cinfo);

    //5.读取一行扫描线数据并处理,通常的代码是这样的
    //成功后buffer里保存的就是解压后的行像素点的数据
    //R G B 从上到下,从左到右
    unsigned char *buffer = malloc(cinfo.output_width * cinfo.output_components);
    printf("start scanline ");
    while(cinfo.output_scanline < cinfo.output_height)
    {
    jpeg_read_scanlines(&cinfo,
    &buffer,//保存解压后的数据的二级指针
    1//扫描的行数
    );
    int x,color;
    unsigned char r,g,b;
    unsigned char *p = buffer;
    for(x = 0; x < 800; x++)
    {
    r = *p++;
    g = *p++;
    b = *p++;

    color = (r << 16) | (g << 8) | b;
    lcdDraw_point(addr,x,cinfo.output_scanline-1,color);
    // int y = cinfo.output_scanline-1;
    // int *pf = (int*)addr;
    // *(pf + 800*y + x) = color;
    }

    }
    printf("finish decompress ");
    //6.完成解压过程
    jpeg_finish_decompress(&cinfo);
    //7.释放资源
    jpeg_destroy_decompress(&cinfo);
    fclose(infile);
    close(fb);

    return 0;

    }

    /*************************************************************************
    > File Name: test_jpeg.c
    > Author: csgec
    > Mail: longer.zhou@gmail.com
    > Created Time: Thu 04 Aug 2016 10:57:30 AM CST
    ************************************************************************/

    #include<stdio.h>
    #include<jpeglib.h>
    #include<fcntl.h>
    #include<sys/mman.h>
    #include<stdlib.h>

    void draw_point(int *p,int x,int y,int color)
    {
    int *pf = p + (800*y + x);
    *pf = color;

    }
    int main(int argc,char ** argv)
    {
    //1
    int fb = open("/dev/fb0",O_RDWR);
    if(fb < 0)
    {
    perror("open");
    return -1;
    }

    //2
    void *addr = mmap(0,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);
    if(addr == MAP_FAILED)
    {
    perror("mmap");
    return -1;
    }

    //-----------利用libjpeg解压jpeg文件的步骤--------------------------------
    //1.分配并初始化一个jpeg解压对象
    printf("start jpeg ");
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_decompress(&cinfo);

    //2.指定要解压的文件
    FILE *infile;
    infile = fopen(argv[1],"r");
    if(infile == NULL)
    {
    fprintf(stderr, "can't open %s ", argv[1]);
    return -1;
    }
    jpeg_stdio_src(&cinfo, infile);

    //3.获取图片信息
    jpeg_read_header(&cinfo, TRUE);

    //4.启动解压过程,cinfo中下面几个成员会比较有用
    //cinfo.output_width 宽_
    //cinfo.output_height 高
    //cinfo.output_components 像素分量(一个像素点占几个字节)
    //cinfo.
    jpeg_start_decompress(&cinfo);

    //5.读取一行扫描线数据并处理,通常的代码是这样的
    //成功后buffer里保存的就是解压后的行像素点的数据
    //R G B 从上到下,从左到右
    unsigned char *buffer = malloc(cinfo.output_width * cinfo.output_components);
    printf("start scanline ");
    while(cinfo.output_scanline < cinfo.output_height)
    {
    jpeg_read_scanlines(&cinfo,
    &buffer,//保存解压后的数据的二级指针
    1//扫描的行数
    );
    int x,color;
    unsigned char r,g,b;
    unsigned char *p = buffer;
    for(x = 0; x < 800; x++)
    {
    r = *p++;
    g = *p++;
    b = *p++;

    color = (r << 16) | (g << 8) | b;
    draw_point(addr,x,cinfo.output_scanline-1,color);
    /*
    int y = cinfo.output_scanline-1;
    int *pf = (int*)addr;
    *(pf + 800*y + x) = color;
    */
    }

    }
    printf("finish decompress ");
    //6.完成解压过程
    jpeg_finish_decompress(&cinfo);
    //7.释放资源
    jpeg_destroy_decompress(&cinfo);
    fclose(infile);
    close(fb);

    return 0;

    }

  • 相关阅读:
    linux(fedora) 下dvwa 建筑环境
    【ThinkingInC++】2、输入和输出流
    Caused by: java.lang.ClassNotFoundException: javax.transaction.TransactionManager
    SpringMVC注释启用
    XML wsdl soap xslt xsl ide
    一个解析RTSP 的URL函数
    PHP:header()函数
    jquery实现鼠标焦点十字效果
    拼出漂亮的表格
    Oracle中如何插入特殊字符:& 和 ' (多种解决方案)
  • 原文地址:https://www.cnblogs.com/liudehao/p/5753972.html
Copyright © 2011-2022 走看看