使用IJG JPEG库
来源:互联网 发布:java测试工程师 编辑:程序博客网 时间:2024/05/01 20:48
此文件描述如何在应用程序中使用IJG JPEG库。 如果你想编写一个使用该库的程序,请阅读它。
文件example.c提供了大量注释的框架代码来调用JPEG库。 另请参阅jpeglib.h(应用程序使用的include文件程序),以获取有关数据结构和函数参数列表的完整详细信息。当然库的源代码是最终的参考。
在尝试使用库进行编程之前,应至少阅读概述和基本用法部分。 有关高级功能的部分如果当你需要他们的时候可以查阅。概述
IJG JPEG库提供C函数来读、写JPEG压缩格式的图像文件。使用JPEG库的应用程序是以"scanline"为单位进行图象处理的。
在JPEG处理中,图像质量与处理速度之间会有折衷。在解压缩处理中更是如此, 解压缩库提供了多种折衷实现,范围从非常高质量到快速预览操作。 在压缩方面,我们通常不提供低质量的选择,因为通常情况下压缩对时间要求不是很严格。 而且,低质量模式可能不满足JPEG标准的准确度要求;
JPEG压缩操作的粗略概述是:
Allocate and initialize a JPEG compression object //分配和初始化compression结构
Specify the destination for the compressed data (eg, a file) //指定压缩后的数据存放的文件
Set parameters for compression, including image size & colorspace //设置压缩参数,包括图像size和colorspace
jpeg_start_compress(...); //启动压缩
while (scan lines remain to be written) //循环调用jpeg_write_scanlines(...),把将要压缩的图像数据从内存缓冲区中写入指定的文件
jpeg_write_scanlines(...);
jpeg_finish_compress(...); //压缩完成
Release the JPEG compression object //释放compression结构
compression结构里保存有压缩参数和工作状态。我们使它的创建/销毁与图像的开始或结束压缩操作分开; 它可以被重复用于一系列图像压缩操作。 这使得对于具有相同压缩参数的图像序列设置变得更加容易。
类似地,JPEG解压缩操作的粗略概述是:
Allocate and initialize a JPEG decompression object // 分配和初始化一个decompression结构
Specify the source of the compressed data (eg, a file) // 指定要解压缩的jpg文件
Call jpeg_read_header() to obtain image info // 用jpeg_read_header获得jpg信息
Set parameters for decompression // 设置解压参数,比如放大、缩小
jpeg_start_decompress(...); // 启动解压:jpeg_start_decompress
while (scan lines remain to be read)
jpeg_read_scanlines(...); // 循环调用jpeg_read_scanlines,把jpg文件解压缩后的数据读取到内存缓冲区中
jpeg_finish_decompress(...); //解压完成
Release the JPEG decompression object // 释放decompression结构
这与压缩概述相似,只是多了获得jpg信息这一步。这是有帮助的,因为当应用程序选择解压缩参数时,有关图像大小,颜色空间等的信息可能会用到。例如,应用程序
可以利用这些信息选择适合于屏幕大小的图像输出缩放比。
基本用法:
在介绍程序细节之前,有必要先了解一下JPEG库的图像数据格式。
图像是像素的矩形阵列,每个像素具有相同数量的component。大多数应用程序将使用RGB数据(每个像素的component数为3)或灰度数据(每个像素的component数为1)。
像素的值都存放在scanlines中,从左到右依次摆放。 例如用于24位RGB颜色的R,G,B,R,G,B,R,G,B,...。 scanline是一个数据类型为JSAMPLE ---的数组,通常是“unsigned char”型的。也就是说scanlines存放的是整个图像的像素值数据,而一个scanline存放的是图像的一行数据。
压缩详细介绍:
1.分配和初始化compression结构。
compression结构的类型为struct jpeg_compress_struct
您还需要定义一个JPEG错误处理程序的结构,即“struct jpeg_error_mgr”(错误处理程序将会打印JPEG错误/警告消息,如果发生致命错误,它将调用exit()退出)。然后调用jpeg_std_error(),将其存储到compression结构的“err”字段中,最后调用jpeg_create_compress()来初始化compression结构的其余部分。
此步骤的代码:
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
...
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_create_compress会分配少量内存,因此如果内存不足,它可能会失败。在这种情况下,它将通过错误处理程序退出; 这就是为什么必须首先初始化错误处理程序。
2.指定压缩后数据存放的文件
此步骤的代码:
FILE * outfile;
...
if ((outfile = fopen(filename, "wb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
exit(1);
}
jpeg_stdio_dest(&cinfo, outfile);
警告:将二进制压缩数据不更改地传送到输出文件至关重要。 在非Unix系统上,stdio库可能执行换行或其他方式损坏二进制数据。 要抑制此行为,您可能需要使用“b”选项来fopen(如上所示)。
您也可以在步骤3设置其他参数时选择数据目的地。 但是您不能在调用jpeg_start_compress()和jpeg_finish_compress()之间更改目的地。
3.设置压缩参数,包括图像大小和色彩空间。
您必须通过在cinfo结构中设置以下字段来提供有关源图像的信息:
image_width //图像宽度,以像素为单位
image_height //图像高度,以像素为单位
input_components // 每个像素的component数
in_color_space //源图像的颜色空间,通常是RGB或灰度
in_color_space字段必须分配一个J_COLOR_SPACE枚举常量,通常为JCS_RGB或JCS_GRAYSCALE。
JPEG还具有大量的压缩参数,决定图像的编码方式。 大多数应用程序不需要知道所有的这些参数。 可以通过调用jpeg_set_defaults()将所有参数设置为合理的默认值;
24位RGB源图像的典型代码是:
cinfo.image_width = Width;
cinfo.image_height = Height;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
4. 开始压缩
在指定数据目的地并设置所有必需的源图像信息和其他参数后,调用jpeg_start_compress()开始压缩。
代码如下:
jpeg_start_compress(&cinfo, TRUE);
“TRUE”参数确保将写入完整的JPEG交换数据流。一旦你调用了jpeg_start_compress(),你不能改变任何JPEG参数或cinfo结构体字段,直到完成压缩循环。
5.把压缩的图像数据从内存缓冲区中写入指定的文件
现在可以通过调用jpeg_write_scanlines()一次或多次写入所有需要的图像数据。在大多数应用中,一次只传递一个scanline是方便的。
图像数据应以从上到下的scanline顺序写入。
cinfo结构体的next_scanline字段表示到目前为止写入的scanline数量。 通常你可以使用这个变量作为循环计数器,所以循环代码可以这么写,“while(cinfo.next_scanline <cinfo.image_height)”。
源图像是3字节RGB像素情况下的代码:
JSAMPROW row_pointer[1]; //该数组用于指向源图像每一行数据的首地址
int row_stride;
row_stride = image_width * 3; //源图像一行的字节数
while (cinfo.next_scanline < cinfo.image_height) {
row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
jpeg_write_scanlines(&cinfo, row_pointer, 1); //第三个参数1表示每次写入一行的数据
}
jpeg_write_scanlines()返回实际写入的scanline数。 这通常等于传入的数字,因此可以忽略返回值。
6.压缩完成
在所有图像数据已经写入之后,调用jpeg_finish_compress()来完成压缩循环。 此步骤是必要的,以表示已将最后一个数据缓冲区写入数据目标。jpeg_finish_compress()也释放相关联的工作内存。
代码如下:
jpeg_finish_compress(&cinfo);
完成压缩循环后,您可以按照下面讨论的方式处理cinfo结构体,也可以使用它压缩另一个图像。 这时,根据不同的情况返回步骤2,3或4。 如果不更改指定文件,新的数据流将写入同一文件。 如果不更改任何JPEG参数,新数据流将使用与之前相同的参数写入。
7.释放cinfo结构。
当你使用完一个cinfo结构,通过调用jpeg_destroy_compress()来销毁它。 这将释放它占有的所有内存。 或者你可以调用jpeg_destroy(),该函数适用于压缩或解压缩结构
代码如下:
jpeg_destroy_compress(&cinfo);
解压缩详细介绍:
1.分配和初始化decompression结构。
该步骤代码:
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
...
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
2.指定要解压缩的jpg文件
此步骤的典型代码如下:
FILE * infile;
...
if ((infile = fopen(filename, "rb")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
exit(1);
}
jpeg_stdio_src(&cinfo, infile);
3.调用jpeg_read_header()获取jpg图像信息
代码如下:
jpeg_read_header(&cinfo, TRUE);
这将读取jpg文件头部信息,文件头部包含图像尺寸和其他信息。 返回时,这些信息会存储在cinfo结构中。 应用程序在选择解压缩参数之前可能会用到此信息。
如果您只想查找jpg文件的图像尺寸和其他信息,完成这步后可以调用jpeg_destroy(),然后选择新数据源并读取它的头部信息。
4.设置解压缩参数
注意,每次调用jpeg_read_header()都会设置所有默认值。如果默认值满足要求,可以跳过这一步。如果您希望在开始解压缩之前更改这些默认值,如 图像缩放比或者选择各种速度/质量权衡,在“解压缩参数选择”一节给出了详细说明。
5.开始解压
参数设置好后,调用jpeg_start_decompress()开始解压缩。 这将初始化内部状态,分配工作内存,并准备返回数据。
代码如下:
jpeg_start_decompress(&cinfo);
在调用之后,解压输出的图像信息会存放在cinfo结构相应的字段中;有用的字段包括:
output_width
output_height
out_color_components
output_components //输出的每个像素占的字节数
colormap
actual_number_of_colors
通常,您将需要分配数据缓冲区来保存解压缩的图像数据。 您需要为每个scanline分配的字节数为:output_width * output_components。解压缩的图像数据包含output_height个scanline。
6.把jpg文件解压缩后的数据读取到内存缓冲区中
现在,您可以通过调用jpeg_read_scanlines()一次或多次读取解压缩的图像数据。 在每次调用时,传入要读取的最大scanline数; 返回值是实际读取的行数。
在cinfo结构的output_scanline字段中保持到目前为止返回的scanline的数量。 通常你可以使用这个变量作为循环计数器,所以循环测试可以这样写
“while(cinfo.output_scanline <cinfo.output_height)”。
7.解压完成
在读取所有图像数据之后,调用jpeg_finish_decompress()来完成解压缩循环,释放工作内存。
代码如下:
jpeg_finish_decompress(&cinfo);
8.释放cinfo结构
当你使用完一个解压缩结构,通过调用jpeg_destroy_decompress()或jpeg_destroy()销毁它。
代码如下:
jpeg_destroy_decompress(&cinfo);
写代码时可以参阅example.c文件。
- 使用IJG JPEG库
- 使用IJG库读写JPEG格式文件
- 使用IJG读写JPEG格式文件
- 使用IJG读写JPEG格式文件
- 使用IJG读写JPEG格式文件
- 使用IJG读写JPEG格式文件
- 使用IJG读写JPEG格式文件
- JPEG转RGB Bmp(IJG库 jpeg.lib)
- IJG JPEG使用说明
- IJG JPEG使用说明
- 如何用Visual Studio编译IJG JPEG库
- 用ijg库在缓冲区中进行jpeg编解码
- ijg jpeg 函数库:文件列表
- ijg jpeg 函数库:代码规则
- IJG JPEG 函数库:文件列表
- IJG JPEG 函数库:文件列表
- IJG JPEG库运行时错误:Corrupt JPEG data 的解决方案
- IJG JPEG库运行时错误:Corrupt JPEG data 的解决方案
- 第九周项目3
- 区块链侧链应用开发平台Asch节点安装及区块生产教程
- 第14周项目1-(3)二叉树排序树的相关算法
- Solr配置文件schema.xml和solrconfig.xml分析
- Failed to resolve: junit:junit:4.12解决方案
- 使用IJG JPEG库
- Dispatch相关知识
- 第十三周项目3--Dijkstra算法的验证
- 第14周 项目1-验证算法
- Tomcat6内存溢出问题解决
- python根据给定的年月日以数字形式打印日期
- 常用win+r运行命令总结
- 第十四周项目1-验证算法(1)-折半查找算法
- Spring配置项<context:annotation-config/>解释说明