WebP开发文档翻译:WebP应用编程接口文档,WebP API Documentation
本小节说明的是,WebP 库中包含的编码器和解码器的应用编程接口。本文档对应的是库的0.5.1 版本。
当妳 安装 libwebp 时, 会在妳的平台的典型位置安装一个名为 webp/ 的目录。例如, 在 Unix系列平台 中,会将以下头文件复制到 /usr/local/include/webp/ 目录。
decode.h
encode.h
types.h
库文件呢,会被放置在通常放置库文件的目录。 在Unix 类平台中,静态 及动态库文件会被放置到 /usr/local/lib/ 目录。
要想使用解码接口,妳首先需要按照 上面 所说的方法将库文件和头文件安装到系统中。
按照以下示例的方式来在妳的C/C++代码中包含解码接口的头文件:
#include "webp/decode.h"
int WebPGetInfo ( const uint8_t* data, size_t data_size, int * width, int * height);
这个函数,会验证WebP 图片的文件头,并且取出图片的宽度和高度。如果 妳不在意图片的尺寸的话,那么,可以将 *width 和 *height 两个指针传递为空指针 ( NULL ) 。
data
指向WebP 图片数据的指针
data_size
data 所指向的图片数据内存块的尺寸。
false
格式有错误,则返回错误码。
true
解析成功 则返回这个。只有 在返回解析成功的情况下, *width 和 *height 中的数据才有效。
width
整数值。其取值范围限制为1到16383。
height
整数值。其取值范围限制为1到16383。
struct WebPBitstreamFeatures {
int width; // 宽度,单位 是像素。
int height; // 高度 ,单位是像素。
int has_alpha; // 如果 这个位流中包含透明通道,则为真( True )。
}
VP8StatusCode WebPGetFeatures ( const uint8_t* data,
size_t data_size,
WebPBitstreamFeatures * features);
这个函数,会从位流中提取出图片的特性。 *features 结构 体的内容,会根据从位流中收集的数据来填充:
data
指向WebP 图片数据的指针
data_size
data 所指向的图片数据内存块的尺寸。
VP8_STATUS_OK
成功提取到特性数据则返回此值。
VP8_STATUS_NOT_ENOUGH_DATA
返回此值,则表示,还需要接收更多数据才能够从文件头中提取出特性信息。
其它情况 下,会返回其它的 VP8StatusCode 错误值。
features
指向一个WebPBitstreamFeatures 结构体的指针。
uint8_t* WebPDecodeRGBA ( const uint8_t* data, size_t data_size, int * width, int * height);
uint8_t* WebPDecodeARGB ( const uint8_t* data, size_t data_size, int * width, int * height);
uint8_t* WebPDecodeBGRA ( const uint8_t* data, size_t data_size, int * width, int * height);
uint8_t* WebPDecodeRGB ( const uint8_t* data, size_t data_size, int * width, int * height);
uint8_t* WebPDecodeBGR ( const uint8_t* data, size_t data_size, int * width, int * height);
这些函数,会 对 data 所指向的WebP 图片数据进行解码。
•. WebPDecodeRGBA 返回RGBA图片数据 ,顺序是 [r0, g0, b0, a0, r1, g1, b1, a1, ...] 。
•. WebPDecodeARGB 返回ARGB图片数据 ,顺序是 [a0, r0, g0, b0, a1, r1, g1, b1, ...] 。
•. WebPDecodeBGRA 返回BGRA图片数据 ,顺序是 [b0, g0, r0, a0, b1, g1, r1, a1, ...] 。
•. WebPDecodeRGB 返回RGB图片数据 ,顺序是 [r0, g0, b0, r1, g1, b1, ...] 。
•. WebPDecodeBGR 返回BGR图片数据 ,顺序是 [b0, g0, r0, b1, g1, r1, ...] 。
对这些函数进行调用的代码,必须使用 WebPFree() 来将这些函数返回的 (uint8_t*) 数据缓冲区释放掉。
data
指向WebP 图片数据的指针
data_size
data 所指向的图片数据内存块的尺寸。
width
整数值。其取值范围限制为1到16383。
height
整数值。其取值范围限制为1到16383。
uint8_t*
指向解码后的WebP 图片数据的指针,其具体数据顺序分别为RGBA/ARGB/BGRA/RGB/BGR。
uint8_t* WebPDecodeRGBAInto ( const uint8_t* data, size_t data_size,
uint8_t* output_buffer, int output_buffer_size, int output_stride);
uint8_t* WebPDecodeARGBInto ( const uint8_t* data, size_t data_size,
uint8_t* output_buffer, int output_buffer_size, int output_stride);
uint8_t* WebPDecodeBGRAInto ( const uint8_t* data, size_t data_size,
uint8_t* output_buffer, int output_buffer_size, int output_stride);
uint8_t* WebPDecodeRGBInto ( const uint8_t* data, size_t data_size,
uint8_t* output_buffer, int output_buffer_size, int output_stride);
uint8_t* WebPDecodeBGRInto ( const uint8_t* data, size_t data_size,
uint8_t* output_buffer, int output_buffer_size, int output_stride);
这些函数是之前所说函数的变种,它们 会将图片直接解码到某个预先分配的缓冲区 output_buffer 中去。 此缓冲区中可用的最大存储空间数量,由 output_buffer_size 参数指定。如果 这块存储空间不够大(或者发生了错误),那么,会返回空值( NULL )。否则 ,会返回 output_buffer ,以便妳日后使用。
参数 output_stride ,指定的是,相邻扫描线之间的距离(单位 是字节 )。因此 ,预期的 output_buffer_size 最小值应当是 output_stride * ( picture.height ) 。
data
指向WebP 图片数据的指针
data_size
data 所指向的图片数据内存块的尺寸
output_buffer_size
整数值。所分配的缓冲区的尺寸
output_stride
整数值。指定相邻扫描线之间的距离。
output_buffer
指向解码后的WebP图片。
uint8_t*
解码成功则返回 output_buffer ;否则返回空值( NULL )。
WebP的解码模块,还支持一个高级接口,可用来在解码的同时进行裁剪和重采样,这种功能对于内存数量受限的环境狠有用,例如移动设备。简单来说,如果妳只是需要解码出一个预览图片或者局部区域放大的图片,而并不完整地解码出原本狠大的原始图片的话,这个过程中所使用的内存,会随着输出图片的尺寸改变,而不是随着输入图片的尺寸改变。并且,在某些情况下,还会节省CPU运算量。
WebP的解码过程,有两种使用方式:一种是,对完整图片进行解码;另一个种,利用较小的输入缓冲区,对图片进行渐进式解码。用户还可以提供一个外部内存缓冲区,以用于图片的解码。以下代码示例,会展示,如何使用高级解码接口。
首先,要初始化一个配置对象:
#include "webp/decode.h"
WebPDecoderConfig config;
CHECK( WebPInitDecoderConfig (&config));
// 此处可调整某些附加解码选项:
config.options.no_fancy_upsampling = 1 ;
config.options.use_scaling = 1 ;
config.options.scaled_width = scaledWidth();
config.options.scaled_height = scaledHeight();
// 狠多选项。
解码选项, 都汇集到了 WebPDecoderConfig 结构体中:
struct WebPDecoderOptions {
int bypass_filtering; // 如果设置 为真(true),则跳过循环体内的过滤流程。
int no_fancy_upsampling; // 如果设置 为真(true),则使用较快的基于点的超采样器(pointwise upsampler)
int use_cropping; // 如果设置 为真(true),则,会 首先 进行裁剪
int crop_left, crop_top; // 裁剪操作 中的左上角位置。
// 会对齐 到偶数值。
int crop_width, crop_height; // 裁剪区域 的尺寸
int use_scaling; // 如果设置 为真(true),会在 最后 进行缩放
int scaled_width, scaled_height; // 缩放 后的最终分辨率
int use_threads; // 如果设置 为真(true),则使用多线程解码
};
或者 ,也可将位流中的各个特性信息读取到 config.input 中去,这样,我们就可以预先得知对应的信息了。例如 ,我们预先知道图片中是否有透明通道的话,也能为后续运行过程提供便利。注意 ,这个 过程中也会对位流的文件头进行解析,因此,也能顺便得知,这个位流是不是一个有效的WebP 图片。
CHECK( WebPGetFeatures (data, data_size, &config.input) == VP8_STATUS_OK);
然后,我们就需要分配好解码过程中所使用的内存缓冲区,以直接提供给解码器,而不是让解码器来分配内存。我们只需要提供三个参数:指向该内存块的指针;缓冲区的总大小;以及,扫描线间距(line stride)(相邻扫描线之间的距离,以字节为单位)。
// 指定预期 的输出颜色空间:
config.output.colorspace = MODE_BGRA;
// 将 config.output指向 一块外部缓冲区:
config.output.u.RGBA.rgba = (uint8_t*)memory_buffer;
config.output.u.RGBA.stride = scanline_stride;
config.output.u.RGBA.size = total_size_of_the_memory_buffer;
config.output.is_external_memory = 1 ;
现在,可以对图片进行解码了。可选用两种方式来对图片进行解码。我们可以一次性对图片进行解码:
CHECK( WebPDecode (data, data_size, &config) == VP8_STATUS_OK);
也可以使用渐进式方法进行解码,随着后续字节的到来而逐渐解析出图片:
WebPIDecoder * idec = WebPINewDecoder (NULL, NULL, &config);
CHECK(idec != NULL);
while (bytes_remaining > 0 ) {
VP8StatusCode status = WebPIAppend (idec, input, bytes_read);
if (status == VP8_STATUS_OK || status == VP8_STATUS_SUSPENDED) {
bytes_remaining -= bytes_read;
} else {
break ;
}
// 上述代码会对当前可用的缓冲区内容进行解码。
// 此刻 ,可通过调用WebPIDecGetRGB()/WebPIDecGetYUVA()等方法来获取到图片中的部分内容。
}
WebPIDelete (idec); // 该对象并不占据图片内存的所有权,因此,可以删除了。
现在,解码后的图片位于config.output中(或者,具体对于本示例来说,位于config.output.u.RGBA中)。可对它进行保存、显示或其它处理。之后,我们只需要回收针对 config 对象所分配的内存。即使该内存是外部分配的,根本就不是由WebPDecode()分配的,也可以安全地调用此函数:
WebPFreeDecBuffer (&config.output);
利用 这个接口,还可以将图片解码成 YUV 和 YUVA格式 ,具体 就是,分别使用 MODE_YUV 和 MODE_YUVA 。 这种格式,也被称作 亮色浓 。
库中提供了某些狠简单的函数,用于将 一些按照常见布局方式排列的RGBA 样本数组编码成图片。 这些函数,都是在 webp/encode.h 头文件中声明的:
size_t WebPEncodeRGB ( const uint8_t* rgb, int width, int height, int stride, float quality_factor, uint8_t** output);
size_t WebPEncodeBGR ( const uint8_t* bgr, int width, int height, int stride, float quality_factor, uint8_t** output);
size_t WebPEncodeRGBA ( const uint8_t* rgba, int width, int height, int stride, float quality_factor, uint8_t** output);
size_t WebPEncodeBGRA ( const uint8_t* bgra, int width, int height, int stride, float quality_factor, uint8_t** output);
质量因子 , quality_factor ,取值范围 是从 0 到 100 。它控制的是,压缩过程中 的信息损耗和图片质量。 值为 0 ,则表示低质量,输出文件尺寸也小。 值为 100 ,则表示,最高质量,输出文件尺寸也最大。如果 编 码成功 ,那么,压缩后的字节数据会被放置到 *output 指针 处, 而其总尺寸会以字节为单位被返回 (失败 则返回 0) 。调用 者必须在日后对 *output 指针调用 WebPFree() 来回收内存。
输入数组 ,应当是 一个紧缩存储的字节数组 (每个颜色通道 一个字节,具体顺序 与函数名字所对应 的顺序一致 ) 。 stride ,表示的是, 从一行跳到下一行的过程中,要跳过的字节个数。例如, BGRA格式应当如下布局:
这些函数,还有对应的无损压缩版本,其格式如下:
size_t WebPEncodeLosslessRGB ( const uint8_t* rgb, int width, int height, int stride, uint8_t** output);
size_t WebPEncodeLosslessBGR ( const uint8_t* bgr, int width, int height, int stride, uint8_t** output);
size_t WebPEncodeLosslessRGBA ( const uint8_t* rgba, int width, int height, int stride, uint8_t** output);
size_t WebPEncodeLosslessBGRA ( const uint8_t* bgra, int width, int height, int stride, uint8_t** output);
编码 器,还提供了若干个高级的编码参数。利用 这些参数,可以更好地 在压缩效率和处理时间之间取得平衡。 这些参数,汇聚在 WebPConfig 结构体中。 这个结构体的最常 用 字段列举如下:
struct WebPConfig {
int lossless; // 无损编码(0= 有损 (默认 值 ) , 1=无损) 。
float quality; // 取值范围 从 0(最小文件尺寸) 到 100(最大文件尺寸)
int method; // 质量/速度之间 的取舍 (0=快速 , 6= 较慢然而质量较好 )
WebPImageHint image_hint; // 图片类型建议(目前 只对无损压缩有效 ) 。
// 以下参数只与有损压缩有关:
int target_size; // 如果 这个字段不为零,则表示,预期的目标文件尺寸,单位是字节。
// 优先 级高于'compression'参数。
float target_PSNR; // 如果 这个字段不为零,则表示,预期达到 的最小失真值。
// 优先 级高于 target_size 。
int segments; // 使用 的最大片断个数,取值范围 [1..4]
int sns_strength; // 立体噪声整形 ( Spatial Noise Shaping )。 0=关闭 , 100=最大 。
int filter_strength; // 范围 : [0 = 关闭 .. 100 = 最强]
int filter_sharpness; // 范围 : [0 = 关闭 .. 7 = 最小锐利 度 ]
int filter_type; // 过滤类型 : 0 = 简单 , 1 = 强 ( 仅当filter_strength > 0 或 autofilter > 0 时才有用 )
int autofilter; // 自动调整过滤 器的强度 [0 = 关闭 , 1 = 开启]
int alpha_compression; // 透明通道平面 的编码算法 (0 = 不使用算法,
// 1 = 按照WebP 无损压缩方式压缩) 。默认值是 1 。
int alpha_filtering; // 对于透明通道平面 的预测式过滤方法。
// 0: 不使用, 1: 快速 , 2: 最佳 。默认值是 1 。
int alpha_quality; // 取值位于0 (最小尺寸) 和 100 (无损)之间 。
// 默认 值是 100 。
int pass ; // 进行 熵分析的遍数 (取值范围[1..10]) 。
int show_compressed; // 如果设置 为真( true ),那么 ,将压缩后的图片导出。
// 不会应用循环体内的过滤。
int preprocessing; // 预处理过滤器 (0= 不使用, 1=片断 式流畅( segment-smooth ) )
int partitions; // log2(标记分区 的个数 ) ,取值范围 [0..3]
// 默认 值是 0 ,以降低渐进式解码的难度。
int partition_limit; // 允许 为了适应预测模式编码中的512k 限制而进行质量降级的程度
// (0: 不进行降级,
// 100: 最大可能 的降级程度 ) 。
};
注意 ,这里的大部分参数, 都可以通过 cwebp 命令行工具来进行试验。
输入 的采样数据,应当被包装在一个 WebPPicture 结构体中。 这个结构体,可以以RGBA 或YUVA 格式来储存输入的采样数据,具体取决于 use_argb 标志位。
结构体,是按照以下方式来组织的:
struct WebPPicture {
int use_argb; // 在ARGB 和YUVA 格式的输入模式之间选择。
// YUV输入模式 ,是针对有损压缩方式的建议输入模式。
// use_argb = 0 则表示使用这个格式。
WebPEncCSP colorspace; // 颜色空间:目前 ,应当使用 YUVA420 或 YUV420(=Y'CbCr) 。
int width, height; // 维度数据(小于 或等于 WEBP_MAX_DIMENSION)
uint8_t *y, *u, *v; // 指向亮度 ( luma ) /色度 ( chroma )平 面 的指针。
int y_stride, uv_stride; // 亮度/色度平 面的扫描线间距( strides )。
uint8_t* a; // 指向透明通道平面 的指针
int a_stride; // 透明通道平面 的扫描线间距( stride )
// 或者使用ARGB格式 的输入,这种格式,是进行无损压缩时建议使用的格式。
// use_argb = 1 则表示使用这个格式。
uint32_t* argb; // 指向argb (32 位 ) 平面 的指针。
int argb_stride; // 扫描 线间距,以像素为单位, 而不是以字节为单位。
// 字节 发射钩子( Byte-emission hook ),用于 在压缩后的字节可用的时刻对它们进行存储。
WebPWriterFunction writer; // 可以为空值( NULL )
void * custom_ptr; // 可由写入器(writer)使用。
// 编码过程 中最后一次发生的错误的错误码
WebPEncodingError error_code;
};
这个结构体中,还包含有一个函数,可用于在产生了压缩后的字节的时刻将它们传输出来。查看下面 的示例, 它是一个内存中的写入器。其它 的写入器,可将数据直接写入文件中 ( examples/cwebp.c 就是一个例子 ) 。
使用高级接口来进行编码的常规流程是:
首先,我们需要创建一个编码配置对象,其它包含着压缩参数。注意,同一个配置对象,可用于压缩日后的多个不同图片。
#include "webp/encode.h"
WebPConfig config;
if (! WebPConfigPreset (&config, WEBP_PRESET_PHOTO, quality_factor)) return 0 ; // 版本 号错误
// 做出额外 的调整:
config.sns_strength = 90 ;
config.filter_sharpness = 6 ;
config.alpha_quality = 90 ;
config_error = WebPValidateConfig (&config); // 验证各个参数 的取值范围 ( 这是个好习惯 )
然而 ,输入的采样数据,需要通过引用 或复制方式传入 到某个 WebPPicture 中。 以下示例,就会分配缓冲区,用于存储采样数据。 不过,妳也可以轻易地创建一个“视图”("view"),指向某个 已分配的采样数据数组。参考 WebPPictureView() 函数以了解细节。
// 设置输入数据 ,分配一个图片对象,其尺寸为 width x height
WebPPicture pic;
if (! WebPPictureInit (&pic)) return 0 ; // 版本 号错误
pic.width = width;
pic.height = height;
if (! WebPPictureAllocate (&pic)) return 0 ; // 内存错误
// 此刻 , 'pic' 已被初始化为一个容器, 可接收 YUVA 或 RGBA采样数据 了。
// 或者 ,也可以使用现成的导入函数,例如 WebPPictureImportRGBA() , 它会处理好
// 内存分配 的事。无论如何 ,在最后,需要调用 WebPPictureFree(&pic)
// 来回收之前分配的内存。
为了将压缩后的字节流传输出来,会在每次有新的字节可用时调用某个钩子函数。 以下是一个简单的示例,使用的是 webp/encode.h 中声明的内存写入器。对于 每张要压缩的图片, 都要进行这种初始化:
// 创建 一个字节写入方法 ( 在这个示例中,写入到内存中 ) :
WebPMemoryWriter writer;
WebPMemoryWriterInit (&writer);
pic.writer = WebPMemoryWrite ;
pic.custom_ptr = &writer;
现在,可以对输入采样数据进行压缩了(日后,要释放它们的内存):
int ok = WebPEncode (&config, &pic);
WebPPictureFree (&pic); // 一定要 将与输入数据相关联的内存释放掉。
if (!ok) {
printf( "Encoding error: %d\n" , pic.error_code);
} else {
printf( "Output size: %d\n" , writer.size);
}
对于 该接口及结构体的更高级用法,建议妳阅读 webp/encode.h 头文件中的文档。阅读示例代码 examples/cwebp.c ,也有助于发现那些不那么常用的参数。
未知美人
Your opinionsHxLauncher: Launch Android applications by voice commands