如何在C项目中集成icer_compression:API调用完整教程(含示例代码)
【免费下载链接】icer_compressionProgressive, error tolerant, wavelet-based image compression algorithm项目地址: https://gitcode.com/gh_mirrors/ic/icer_compression
icer_compression 是一个基于 NASA ICER 算法的 C 语言图像压缩库,采用渐进式、小波变换(wavelet)压缩方案,专为内存受限的嵌入式系统设计,同时也能在普通桌面环境下高效运行。本文将带你从零开始,完成 icer_compression 的 C 项目集成,手把手演示压缩与解压的核心 API 调用方法,并附上可直接运行的示例代码,帮助你快速把这款容错能力强、可设定输出大小的图像压缩算法用在自己的项目里。
上图展示了 icer_compression 的压缩效果:512×512 的原始灰度图(262KB)在 70KB 字节配额下依然保持清晰的主体结构,这正是错误隔离分段(error containment segments)与小波变换结合的威力。
icer_compression 是什么?NASA ICER 算法的 C 语言实现
ICER 算法最早由 NASA 为深空通信场景设计,主要解决"数据在传输中可能丢失"这一痛点。作为它的 C 语言实现,icer_compression 继承了以下核心特性:
- ✅渐进式压缩:可设置目标字节配额,达到配额即停止编码
- ✅错误容错:将图像划分为多个错误隔离段,单段损坏不影响整图
- ✅纯整数运算:全程不使用浮点,非常适合嵌入式 MCU
- ✅零动态内存分配:库内部不 malloc,内存可完全由用户掌控
- ✅支持 8 位与 16 位像素:灰度与 YUV 彩色图像均可处理
相关源码可以参考 lib_icer/inc/icer.h(全部 API 声明)与 lib_icer/CMakeLists.txt(库的构建配置)。
第一步:克隆源码并编译 C 项目
集成前需要先把项目拉取到本地并编译出静态库。克隆命令如下:
git clone https://gitcode.com/gh_mirrors/ic/icer_compression cd icer_compression mkdir build && cd build cmake -DCMAKE_BUILD_TYPE=Release .. make编译完成后会生成libicer.a静态库,以及compress、decompress、compress_color、decompress_color四个集成示例程序和命令行工具icer_util。你可以先用icer_util快速感受压缩效果:
./icer_util compress input.jpg output.bin --grayscale ./icer_util decompress output.bin output.bmp --grayscale命令行工具的完整参数说明见 example/src/icer_util.c。
第二步:集成前的必要配置(编译宏与初始化)
在 C 项目中引入 icer_compression,只需要三步:
① 配置编译宏:在包含头文件之前,用#define声明需要编译的功能模块:
#define USE_ENCODE_FUNCTIONS // 启用压缩函数 #define USE_DECODE_FUNCTIONS // 启用解压函数 #define USE_UINT16_FUNCTIONS // 使用 16 位像素接口 #define USE_UINT8_FUNCTIONS // 使用 8 位像素接口 #include "icer.h"② 链接库:编译时加上-licer,并把lib_icer/inc加入头文件搜索路径。
③ 调用初始化函数:程序启动后、首次压缩前,必须执行一次:
int res = icer_init(); if (res != ICER_RESULT_OK) { printf("ICER 初始化失败,错误码:%d\n", res); return -1; }icer_init()负责初始化熵编码器、CRC32 查表等全局常量,详见 lib_icer/src/icer_init.c。
第三步:核心 API 调用——压缩一张灰度图像
压缩灰度图像最简单的方式是调用icer_compress_image_uint16(对应 8 位版本为icer_compress_image_uint8)。参考 example/src/example_encode.c 的实现,核心流程如下:
uint16_t *image; // 图像像素数据(灰度) size_t w = 512, h = 512; // 图像宽高 uint8_t stages = 4; // 小波分解级数 enum icer_filter_types filt = ICER_FILTER_A; // 滤波器类型 uint8_t segments = 6; // 错误隔离段数量 // 1. 准备输出缓冲区(分配 2 倍配额 + 余量) uint8_t *datastream = malloc(30000 * 2 + 500); icer_output_data_buf_typedef output; icer_init_output_struct(&output, datastream, 30000 * 2, 30000); // 2. 执行压缩,30000 字节为目标配额 int res = icer_compress_image_uint16(image, w, h, stages, filt, segments, &output); if (res != ICER_RESULT_OK && res != ICER_BYTE_QUOTA_EXCEEDED) { printf("压缩失败,错误码:%d\n", res); } // 3. 压缩结果写入文件 fwrite(output.rearrange_start, 1, output.size_used, fp);这里的关键是icer_init_output_struct的第三个参数(字节配额):它直接决定了压缩的"目标大小",配额越小压缩率越高,图像质量相应下降。
第四步:彩色图像压缩——YUV 三通道 API 调用
彩色图像的 API 调用稍微复杂,需要先把 RGB 转为 YUV 三个通道,再调用icer_compress_image_yuv_uint16。完整转换代码见 example/src/example_encode_color.c 中的rgb888_packed_to_yuv函数:
uint16_t *y_channel, *u_channel, *v_channel; // 三个 YUV 通道缓冲 int res = icer_compress_image_yuv_uint16( y_channel, u_channel, v_channel, // Y、U、V 通道 w, h, // 图像宽高 stages, filt, segments, // 级数、滤波器、分段数 &output // 输出缓冲 );彩色模式内部会对 Y 通道(亮度)和 U/V 通道(色度)分别建模,编码效率更高。下面这张图展示了彩色模式在 140KB 配额下的压缩效果:
第五步:解压 API 调用——还原图像
解压是对称操作,调用icer_decompress_image_uint16即可。一个实用的技巧是先用icer_get_image_dimensions从压缩流中读出图像尺寸,再分配解压缓冲,参考 example/src/example_decode.c:
// 1. 从压缩流中获取图像尺寸,避免盲目分配 size_t img_w, img_h; icer_get_image_dimensions(datastream, data_length, &img_w, &img_h); // 2. 分配解压缓冲并调用解压 API uint16_t *image = malloc(img_w * img_h * sizeof(uint16_t)); size_t out_w, out_h; int res = icer_decompress_image_uint16( image, &out_w, &out_h, img_w * img_h, // 缓冲区容量 datastream, data_length, stages, filt, segments // 必须与压缩时参数一致! ); if (res != ICER_RESULT_OK) { printf("解压失败,错误码:%d\n", res); }⚠️重要提醒:解压时传入的stages、filt、segments必须与压缩时完全一致,否则无法正确还原图像。
参数调优指南:让压缩效果更理想
| 参数 | 取值范围 | 作用与建议 |
|---|---|---|
stages小波级数 | 1~6 | 级数越多压缩率越高,但细节损失越大;默认 4 是平衡点 |
filt滤波器 | A~F、Q | A 为通用默认值,不同滤波器对不同图像内容敏感 |
segments分段数 | 1~32 | 分段越多容错越强,但压缩率略微下降 |
| 字节配额 | >0 | 直接控制输出大小,配额越大质量越好 |
这些宏的上限可在 lib_icer/inc/icer.h 中通过ICER_MAX_SEGMENTS、ICER_MAX_DECOMP_STAGES等预定义调整,方便按嵌入式平台的内存大小裁剪。
常见错误码速查表
API 返回值为负时表示出错,最常见的有:
ICER_BYTE_QUOTA_EXCEEDED (-5):已达到字节配额,属正常截断(压缩成功)ICER_OUTPUT_BUF_TOO_SMALL (-2):输出缓冲区不足,需增大分配ICER_DECODED_INVALID_DATA (-8):解压数据校验失败,参数可能不匹配ICER_INVALID_INPUT (-11):输入参数非法(如宽高为 0)
完整错误码定义见 lib_icer/inc/icer.h 中的enum icer_status。
总结
本文从克隆源码、CMake 编译,到icer_init()初始化、灰度/彩色压缩 API 调用、解压还原,完整演示了 icer_compression 在 C 项目中的集成全流程。作为一款源自 NASA 的渐进式小波图像压缩算法,它最大的价值在于错误容错 + 目标字节配额这两大能力,非常适合卫星通信、遥感图像、嵌入式设备等对数据可靠性和内存占用敏感的场景。动手跑一遍示例代码(example/src/),你就能直观感受到它的压缩效率与集成的便捷性。
【免费下载链接】icer_compressionProgressive, error tolerant, wavelet-based image compression algorithm项目地址: https://gitcode.com/gh_mirrors/ic/icer_compression
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考