jpeglib库的基本使用

libjpeg是一个完全用C语言编写的库,包含了被广泛使用的JPEG解码、JPEG编码和其他的JPEG功能的实现。这个库由独立JPEG工作组维护。

官网:http://www.ijg.org/

源码:http://www.ijg.org/files/jpegsrc.v9b.tar.gz

 

实验上位机:itop-4412

 

移植步骤:

./configure --host=arm-linux    --prefix=/opt/crosstool/arm-2009q3/arm-none-linux-gnueabi/libc/usrmake     -----(安装到交叉编译工具标准c库的目录下)

make install

上面安装到编译器中,同时也要安装到根文件系统中

/configure --host=arm-linux --prefix=/opt/lrdfs/usr --- (我的根文件放在/opt/lrdfs下)

make install

 

压缩:

输入RGB数据,输出jpeg数据

(参考example.c中的代码)

/*

* image_buffer : rgb数据

* filename: 输出jpg的文件名

* quality : 压缩质量

*/

GLOBAL(void)

write_JPEG_file (char * filename, int quality, unsigned char *image_buffer)

{

struct jpeg_compress_struct com_cinfo;

struct jpeg_error_mgr com_jerr;

 

  FILE * outfile;      /* target file */

  JSAMPROW row_pointer[1];  /* pointer to JSAMPLE row[s] 一行位图 */

  int row_stride;      /* physical row width in image buffer */

  /* Step 1: 申请并初始化jpeg压缩对象,同时要指定错误处理器

 */

  com_cinfo.err = jpeg_std_error(&com_jerr);

  /* Now we can initialize the JPEG compression object. */

  jpeg_create_compress(&com_cinfo);

 /* Step 2: 指定压缩后的图像所存放的目标文件,注意目标文件应以二进制模式打开

 */

  if ((outfile = fopen(filename, "wb")) == NULL) {

    fprintf(stderr, "can't open %s\n", filename);

    exit(1);

  }

  jpeg_stdio_dest(&com_cinfo, outfile);

  /* Step 3: 设置压缩参数 */

     /* image width and height, in pixels */

  com_cinfo.image_width = img_width;

  com_cinfo.image_height = img_height;

  com_cinfo.input_components = 3;    /* 3表示彩色位图,如果是灰度图则为1 */

  com_cinfo.in_color_space = JCS_RGB; /* JCS_RGB表示彩色图像 */

  /* jpeg_set_defaults函数一定要等设置好图像宽、高、色彩通道数计色彩空间四个参数后才能调用,因为这个函数要用到这四个值,调用jpeg_set_defaults函数后,libjpeg库采用默认的设置对图像进行压缩,如果需要改变设置,如压缩质量,调用这个函数后,可以调用其它设置函数,如jpeg_set_quality函数。其实图像压缩时有好多参数可以设置,但大部分我们都用不着设置,只需调用jpeg_set_defaults函数值为默认值即可。   */

  jpeg_set_defaults(&com_cinfo);

  jpeg_set_quality(&com_cinfo, quality, TRUE /* limit to baseline-JPEG values */);

/* jpeg_start_compress,然后可以对每一行进行压缩,也可以对若干行进行压缩,甚至可以对整个的图像进行一次压缩,压缩完成后,要调用jpeg_finish_compress函数*/

  /* Step 4: Start compressor */

  jpeg_start_compress(&com_cinfo, TRUE);

  /* Step 5: while (scan lines remain to be written) */

  row_stride = img_width * 3;    /* JSAMPLEs per row in image_buffer  每一行的字节数*/

  //对每一行进行压缩

  while (com_cinfo.next_scanline < com_cinfo.image_height) {

         row_pointer[0] = & image_buffer[com_cinfo.next_scanline * row_stride];  // image_buffer指向要压缩的数据  

 jpeg_write_scanlines(&com_cinfo, row_pointer, 1);

  }

/*最后就是释放压缩工作过程中所申请的资源了*/

  /* Step 6: Finish compression */

  jpeg_finish_compress(&com_cinfo);

  fclose(outfile);

  /* Step 7: release JPEG compression object */

  jpeg_destroy_compress(&com_cinfo);

  /* And we're done! */

}

 

 

解压:输入:jpg文件,输出:rgb数据

/* jpg_buffer : jpg文件数据

 * file_info : jpg文件的状态信息

 */

int jpg_depress(unsigned char *jpg_buffer, struct stat file_info )

{

     //2 声明解压缩结构体,以及错误管理结构体

     struct jpeg_decompress_struct cinfo; //解压结构体

     struct jpeg_error_mgr jerr;

 

     // 使用缺省的出错处理来初始化解压缩结构体

     cinfo.err = jpeg_std_error(&jerr);

     jpeg_create_decompress(&cinfo);

 

     // 配置该cinfo,使其从jpg_buffer中读取jpg_size个字节

     // 这些数据必须是完整的JPEG数据

     jpeg_mem_src(&cinfo, jpg_buffer, file_info.st_size);

 

     // 读取JPEG文件的头,并判断其格式是否合法

     int ret = jpeg_read_header(&cinfo, true);

     if(ret != 1)

     {

         fprintf(stderr, "[%d]: jpeg_read_header failed: "

              "%s\n", __LINE__, strerror(errno));

         exit(1);

     }

     // 开始解压

     jpeg_start_decompress(&cinfo);

 

     imageinfo.width = cinfo.output_width;

     imageinfo.height = cinfo.output_height;

     imageinfo.pixel_size = cinfo.output_components;

 

     int row_stride = imageinfo.width * imageinfo.pixel_size;

 

     // 根据图片的尺寸大小,分配一块相应的内存bmp_buffer

     // 用来存放从jpg_buffer解压出来的图像数据

     bmp_size = imageinfo.width *

              imageinfo.height * imageinfo.pixel_size;

     bmp_buffer = (unsigned char *)calloc(1, bmp_size);

 

     // 循环地将图片的每一行读出并解压到bmp_buffer

     int line = 0;

     while(cinfo.output_scanline < cinfo.output_height)

     {

         unsigned char *buffer_array[1];

         buffer_array[0] = bmp_buffer +

                   (cinfo.output_scanline) * row_stride;

         jpeg_read_scanlines(&cinfo, buffer_array, 1);

     }

     // 解压完了,将jpeg相关的资源释放掉

     jpeg_finish_decompress(&cinfo);

     jpeg_destroy_decompress(&cinfo);

     free(jpg_buffer);

 

     return 0;

}

 

 

 

一点题外话:

一、YUV420格式
先Y,后V,中间是U。其中的Y是w * h,U和V是w/2 * (h/2)
如果w = 4,h = 2,则:
yyyy
yyyy
uu
vv

内存则是:yyyyyyyyuuvv
需要占用的内存:w * h * 3 / 2
采样规律是:每个像素点都采样Y,奇数行采样1/2个U,不采样V,偶数行采样1/2个V,不采样U

二、YUV422格式
本格式使用较为广泛
每两个点为一组,共占用4个字节
YUYVYUYV
对于每一组YUYV,前面一个Y和本组中的UV组成第一个点,第二个Y和本组中的UV组成第二个点
所以,在内存中,宽高分别为w * 2、h。
如果w = 4,h = 2,则:
YUYVYUYV
YUYVYUYV

需要占用的内存:w * h * 2

三、UYUY422格式

本格式和YUYV422一样,只是YUV的位置不一样罢了

每组中YUV的排列顺序为:UYUV

 需要占用的内存:w * h * 2

 

  • 1
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
libjpeg是一种用C语言编写的 JPEG 图像压缩与解压缩,它提供了一些函数用于压缩和解压缩 JPEG 图像。在使用 libjpeg 之前,需要先安装 libjpeg 。 安装方法: 在 Linux 中,可以使用以下命令安装 libjpeg : sudo apt-get install libjpeg-dev 在 Windows 中,可以从官网下载 libjpeg 并进行安装。 使用方法: 1. 引入头文件 在需要使用 libjpeg 的源文件中,需要包含以下头文件: #include <stdio.h> #include <stdlib.h> #include <jpeglib.h> 2. 定义结构体 使用 libjpeg 时需要定义一些结构体,例如: struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; 3. 初始化压缩器或解压器 在使用压缩或解压功能之前,需要分别初始化压缩器或解压器,例如: // 初始化压缩器 jpeg_create_compress(&cinfo); // 初始化解压器 jpeg_create_decompress(&cinfo); 4. 设置参数 在使用压缩或解压功能之前,需要设置一些参数,例如: // 设置压缩图像的宽度和高度 cinfo.image_width = width; cinfo.image_height = height; // 设置颜色空间 cinfo.in_color_space = JCS_RGB; // 设置压缩品质 jpeg_set_quality(&cinfo, quality, TRUE); 5. 执行压缩或解压 设置完参数之后,可以执行压缩或解压操作,例如: // 执行压缩 jpeg_start_compress(&cinfo, TRUE); jpeg_write_scanlines(&cinfo, buffer, height); jpeg_finish_compress(&cinfo); // 执行解压 jpeg_start_decompress(&cinfo); jpeg_read_scanlines(&cinfo, buffer, height); jpeg_finish_decompress(&cinfo); 6. 销毁结构体 使用完压缩或解压功能后,需要销毁相应的结构体,例如: // 销毁压缩器 jpeg_destroy_compress(&cinfo); // 销毁解压器 jpeg_destroy_decompress(&cinfo); 以上是 libjpeg 基本使用方法,具体可以参考官方文档。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值