将一张JPEG图片通过嵌入式linux的帧缓冲机制绘制到7寸触摸屏上

来源:互联网 发布:酷家乐在线设计软件 编辑:程序博客网 时间:2024/04/30 20:13

1.移植libjpeg库

 转载自:http://blog.sina.com.cn/s/blog_68282f2e0102uyeo.html

本文主要讲如何把libjpeg库移植到mini2440arm板上。(我用的是友善tiny6410)

我的系统:Fedora11
编译工具:arm-linux-gcc
第一步下载libjpeg库
下载地址http://www.ijg.org/
下载jpegsrc.v9a.tar.gz这个文件
第二步
解压这个文件
第三步
打开终端,切换到解压的目录
执行
./configure --prefix=/usr/local/lib CC=arm-linux-gcc --host=arm-linux --enable-shared --enable-static     (prefix可以自己指定)
第四步
执行
make
可能需要几分钟。
执行
make install 

第五步
库的使用
arm-linux-gcc -o 你的输出 你的程序 -L/usr/local/lib -l:libjpeg.so.9

2.编写实现代码

转载自:http://blog.csdn.net/angle_birds/article/details/8647365

代码:

#include    <stdio.h>#include    <string.h>#include    <stdlib.h>#include    <unistd.h>#include    <sys/ioctl.h>#include    <sys/types.h>#include    <sys/stat.h>#include    <errno.h>#include    <fcntl.h>#include    <sys/mman.h>#include    <linux/fb.h>#include    "jpeglib.h"#include    "jerror.h"#define FB_DEV  "/dev/fb0"#define __fnc__ __FUNCTION__#define debug           0#define debug_printf    0#define BYREAD          0#define BYMEM           1/* function deciaration */void usage(char *msg);unsigned short RGB888toRGB565(unsigned char red,        unsigned char green, unsigned char blue);int fb_open(char *fb_device);int fb_close(int fd);int fb_stat(int fd, unsigned int *width, unsigned int *height, unsigned int *    depth);void *fb_mmap(int fd, unsigned int screensize);void *fd_mmap(int fd, unsigned int filesize);int fb_munmap(void *start, size_t length);int fb_pixel(void *fbmem, int width, int height,        int x, int y, unsigned short color);#if(debug)void draw(unsigned char *fbp,        struct fb_var_screeninfo vinfo,        struct fb_fix_screeninfo finfo);#endif/* function implementation */int main(int argc, char **argv){    struct jpeg_decompress_struct cinfo;    struct jpeg_error_mgr jerr;#if(BYREAD)    FILE *infile;#endif    int fd;    unsigned char *buffer;    struct stat st;    int fbdev;    char *fb_device;    unsigned char *fbmem;    unsigned char *fdmem;    unsigned int screensize;    unsigned int fb_width;    unsigned int fb_height;    unsigned int fb_depth;    register unsigned int x;    register unsigned int y;    /* check auguments */    if (argc != 2) {        usage("insuffient auguments");        exit(-1);    }    /* open framebuffer device */    if ((fb_device = getenv("FRAMEBUFFER")) == NULL)        fb_device = FB_DEV;    fbdev = fb_open(fb_device);    /* get status of framebuffer device */    fb_stat(fbdev, &fb_width, &fb_height, &fb_depth);    /* map framebuffer device to shared memory */    screensize = fb_width * fb_height * fb_depth / 8;    fbmem = fb_mmap(fbdev, screensize);#if (BYREAD)    /* open input jpeg file */    if ((infile = fopen(argv[1], "rb")) == NULL) {        fprintf(stderr, "open %s failed\n", argv[1]);        exit(-1);    }#endif    if ((fd = open(argv[1], O_RDONLY)) < 0) {        perror("open");        exit(-1);    }    if (fstat(fd, &st) < 0) {        perror("fstat");        exit(-1);    }    fdmem = fd_mmap(fd, st.st_size);    /* init jpeg decompress object error handler */    cinfo.err = jpeg_std_error(&jerr);    jpeg_create_decompress(&cinfo);    /* bind jpeg decompress object to infile */#if (BYREAD)    jpeg_stdio_src(&cinfo, infile);#endif#if (BYMEM)    jpeg_mem_src(&cinfo, fdmem, st.st_size);#endif    /* read jpeg header */    jpeg_read_header(&cinfo, TRUE);    /* decompress process */    jpeg_start_decompress(&cinfo);    if ((cinfo.output_width > fb_width) ||            (cinfo.output_height > fb_height)) {        printf("too large jpeg file, can't display\n");#if (0)        return -1;#endif    }    buffer = (unsigned char *) malloc(cinfo.output_width *            cinfo.output_components);    struct fb_fix_screeninfo fb_finfo;    struct fb_var_screeninfo fb_vinfo;    if (ioctl(fbdev, FBIOGET_FSCREENINFO, &fb_finfo)) {        perror(__fnc__);        return -1;    }    if (ioctl(fbdev, FBIOGET_VSCREENINFO, &fb_vinfo)) {        perror(__fnc__);        return -1;    }#if(debug)    draw(fbmem, fb_vinfo, fb_finfo);#endif    y = 0;    while (cinfo.output_scanline < cinfo.output_height) {        jpeg_read_scanlines(&cinfo, &buffer, 1);        if (fb_depth == 16) {            unsigned short color;            for (x = 0; x < cinfo.output_width; x++) {                color =                    RGB888toRGB565(buffer[x * 3],                            buffer[x * 3 + 1], buffer[x * 3 + 2]);                fb_pixel(fbmem, fb_width, fb_height, x, y, color);            }        } else if (fb_depth == 24) {            memcpy((unsigned char *) fbmem + y * fb_width * 3,                    buffer, cinfo.output_width * cinfo.output_components);        } else if (fb_depth == 32) {            // memcpy((unsigned char *) fbmem + y * fb_width * 4,                    // buffer, cinfo.output_width * cinfo.output_components);            for (x = 0; x < cinfo.output_width; x++) {                * (fbmem + y * fb_width * 4 + x * 4)     = (unsigned char)       buffer[x * 3 + 2];                * (fbmem + y * fb_width * 4 + x * 4 + 1) = (unsigned char)       buffer[x * 3 + 1];                * (fbmem + y * fb_width * 4 + x * 4 + 2) = (unsigned char)       buffer[x * 3 + 0];                * (fbmem + y * fb_width * 4 + x * 4 + 3) = (unsigned char) 0;            }        }        y++;    // next scanline    }    /* finish decompress, destroy decompress object */    jpeg_finish_decompress(&cinfo);    jpeg_destroy_decompress(&cinfo);    /* release memory buffer */    free(buffer);#if (BYREAD)    /* close jpeg inputing file */    fclose(infile);#endif    /* unmap framebuffer's shared memory */    fb_munmap(fbmem, screensize);#if (BYMEM)    munmap(fdmem, (size_t) st.st_size);    close(fd);#endif    /* close framebuffer device */    fb_close(fbdev);    return 0;}void usage(char *msg){    fprintf(stderr, "%s\n", msg);    printf("Usage: fv some-jpeg-file.jpg\n");}/* open framebuffer device. * return positive file descriptor if success, * else return -1 */int fb_open(char *fb_device){    int fd;    if ((fd = open(fb_device, O_RDWR)) < 0) {        perror(__fnc__);        return -1;    }    return fd;}int fb_close(int fd){    return (close(fd));}/* get framebuffer's width, height, and depth. * return 0 if success, else return -1. */int fb_stat(int fd, unsigned int *width, unsigned int *height, unsigned int *    depth){    struct fb_fix_screeninfo fb_finfo;    struct fb_var_screeninfo fb_vinfo;    if (ioctl(fd, FBIOGET_FSCREENINFO, &fb_finfo)) {        perror(__fnc__);        return -1;    }    if (ioctl(fd, FBIOGET_VSCREENINFO, &fb_vinfo)) {        perror(__fnc__);        return -1;    }    *width = fb_vinfo.xres;    *height = fb_vinfo.yres;    *depth = fb_vinfo.bits_per_pixel;    return 0;}/* map shared memory to framebuffer device. * return maped memory if success * else return -1, as mmap dose */void *fb_mmap(int fd, unsigned int screensize){    caddr_t fbmem;    if ((fbmem = mmap(0, screensize, PROT_READ | PROT_WRITE,                    MAP_SHARED, fd, 0)) == MAP_FAILED) {        perror(__func__);        return (void *) (-1);    }    return fbmem;}/* map shared memmory to a opened file */void *fd_mmap(int fd, unsigned int filesize){    caddr_t fdmem;    if ((fdmem = mmap(0, filesize, PROT_READ,                    MAP_SHARED, fd, 0)) == MAP_FAILED) {        perror(__func__);        return (void *) (-1);    }    return fdmem;}/* unmap map memory for framebuffer device */int fb_munmap(void *start, size_t length){    return (munmap(start, length));}/* convert 24bit RGB888 to 16bit RGB565 color format */unsigned short RGB888toRGB565(unsigned char red,        unsigned char green, unsigned char blue){    unsigned short B = (blue >> 3) & 0x001F;    unsigned short G = ((green >> 2) << 5) & 0x07E0;    unsigned short R = ((red >> 3) << 11) & 0xF800;    return (unsigned short) (R | G | B);}/* display a pixel on the framebuffer device. * fbmem is the starting memory of framebuffer, * width and height are dimension of framebuffer, * width and height are dimension of framebuffer, * x and y are the coordinates to display, * color is the pixel's color value. * return 0 if success, otherwise return -1. */int fb_pixel(void *fbmem, int width, int height,        int x, int y, unsigned short color){    if ((x > width) || (y > height))        return -1;    unsigned short *dst = ((unsigned short *) fbmem + y * width + x);    *dst = color;    return 0;}

编译命令:

arm-linux-gcc -o fb_jpeg fb_jpeg.c -I/workspace/tiny6410/libjpeg/jpeg-9a/install/include -L/workspace/tiny6410/libjpeg/jpeg-9a/install/lib -l:libjpeg.so.9


3.在板测试

设置好LD_LIBRARY_PATH指向刚才编译出来的libjpeg安装目录下的lib目录,然后运行./fb_jpeg /sdcard/image.jpg

测试效果:


(-------------------仅供参考交流-----------------------)


0 1
原创粉丝点击