linux图像显示(三)使用libjpg处理jpg图片

linux图像显示

linux图像显示(一)framebuffer操作

linux图像显示(二)bmp图片

linux图像显示(三)使用libjpg处理jpg图片

linux图像显示(四)使用libpng处理png图片

linux图像显示(五)使用freetype处理矢量字体

移植libjpg

移植libjpeg到arm板上,我们主要是要得到动态链接库.so,静态链接库.a,头文件.h

具体步骤如下

1,下载的libjpeg

可通过下面网址下载

https://sourceforge.net/projects/libjpeg/

2,解压

在ubuntu下随便找一个目录解压tar -vxf jpegsrc.v6b.tar.gz

3,配置

(1)./ configure --prefix = / opt / lib_jpeg / --exec-prefix = / opt / lib_jpeg / --enable-shared --enable-static -build = i386 -host = arm

其中--prefix和--exec-prefix是你将生成的库文件安装到哪个目录下,这个目录可以自定义

(2)配置之后就会生成生成文件

    ①打开的Makefile

     在头几行会发现

     prefix = / opt / lib_jpeg /  
     exec_prefix = / opt / lib_jpeg /
     bindir = $(exec_prefix)/ bin
     libdir = $(exec_prefix)/ lib
     includedir = $(prefix)/ include

      我们需要在之前指定的目录下分别建立bin,lib,包括目录

  ②修改生成文件使用的编译器

    CC = gcc - > CC = arm-linux-gcc

    AR = ar rc - > AR = arm-linux-ar rc

    AR2 = ranlib - > AR2 = arm-linux-ranlib

4、编译并安装

    make && make install-lib

我们就能在我们之前指定的目录下看到生成了对应的库文件和头文件

5.接下来将库和头文件添加到我们的工程中

(1).添加头文件路径:

在Makefile中添加

        CFLAGS += -I/opt/lib_jpeg/include

(2).添加链接库文件:分为两步

①使用-L添加库文件路径
        LDFLAGS := -L/opt/lib_jpeg/lib

②使用-l添加库文件名称
        LDFLAGS := -ljpeg (添加libjpeg)

(3).添加 动态库.so 到开发板根文件系统

由于动态库在程序运行时需要使用到,所以我们需要将动态库添加到开发板的根文件系统中

有两种方式添加

①添加到系统指定的目录
            /lib
            /usr/lib

②添加到自定义路径,导出到环境变量告诉操作系统
            export LD_LIBRARY_PATH=path:$LD_LIBRARY_PATH
          查看是否添加成功  echo $LD_LIBRARY_PATH

到这里,我们的移植就已经完成了

示例代码

参考了example.c的代码,简单修改得到以下代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <setjmp.h>
#include <jpeglib.h>

/* 错误处理相关 */
struct my_error_mgr {
    struct jpeg_error_mgr pub;	

    jmp_buf setjmp_buffer;	
};

typedef struct my_error_mgr * my_error_ptr;

METHODDEF(void)
my_error_exit (j_common_ptr cinfo)
{
    /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
    my_error_ptr myerr = (my_error_ptr) cinfo->err;

    /* Always display the message. */
    /* We could postpone this until after returning, if we chose. */
    (*cinfo->err->output_message) (cinfo);

    /* Return control to the setjmp point */
    longjmp(myerr->setjmp_buffer, 1);
}

static int analogize_jpeg_pirture(const char *file_path)
{
    struct jpeg_decompress_struct cinfo;
    struct my_error_mgr jerr;
    FILE * infile; /* 文件句柄 */
    int image_width, image_height;
	
    /* 从源码中可以知道这是一个指向指针的指针 */
    JSAMPARRAY buffer = NULL; /* 一行图形数据存储的地方 */
    int row_stride; /* 一行数据的字节数 */

    /* 以二进制方式打开图像文件 */
    if ((infile = fopen(file_path, "rb")) == NULL) 
    {
        fprintf(stderr, "can't open %s\n", file_path);
        return -1;
    }

    /* 1.分配和初始化cinfo */

    /* 绑定错误处理函数 */
    cinfo.err = jpeg_std_error(&jerr.pub);
    jerr.pub.error_exit = my_error_exit;

    /* 错误处理 */
    if (setjmp(jerr.setjmp_buffer)) 
    {
        jpeg_destroy_decompress(&cinfo);
        fclose(infile);
        return -1;
    }
    
    /* 初始化cinfo */
    jpeg_create_decompress(&cinfo);

    /* 2.初始化cinfo */
    jpeg_stdio_src(&cinfo, infile);

    /* 3.读取文件头 */
    jpeg_read_header(&cinfo, TRUE);

    /* 4.开始解压 */
    jpeg_start_decompress(&cinfo);

    /* 记录下图像的宽度和高度,给图像数据存储区分配内存 */
    image_width = cinfo.output_width;
    image_height = cinfo.output_height;
	
	/* 自己定义的图像存储区 */
	char *p_image_buf;
    p_image_buf = (unsigned char *)malloc(abs(image_width * image_height * 3));

    /* 一行字节数 = 行宽 * 每个像素点字节数 */
    row_stride = cinfo.output_width * cinfo.output_components; 

    /* 给libjpeg所需要的行缓存分配内存空间 */
    buffer = (*cinfo.mem->alloc_sarray)
            ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); 

    /* 5.一行一行地扫描图像 */
    while (cinfo.output_scanline < cinfo.output_height) 
    {
        /* 读取一行图像 */
        jpeg_read_scanlines(&cinfo, buffer, 1);

        /* 将一行图像数据保存起来 */
        memcpy(p_image_buf + ((cinfo.output_scanline - 1) * row_stride), buffer[0], row_stride); /* 特别注意buffer[0] */
    }
    
    /* 6.结束解压 */
    jpeg_finish_decompress(&cinfo);

    /* 7.释放内存 */
    jpeg_destroy_decompress(&cinfo);

    fclose(infile);

    return 0;
}

需要特别注意的是JSAMPARRAY buffer;

这是一个指向指针的指针,要获取一行图像的数据需要使用buffer[0]

关于如何移植libjpeg到arm开发板请参考:https://blog.csdn.net/weixin_42462202/article/details/84900414

发布了107 篇原创文章 · 获赞 197 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/weixin_42462202/article/details/84928618