webp格式可以大幅压缩图像的数据大小, 比png和jpg还要高很多, 具体高多少网上一堆,不做过多叙述, 直接上例子
1:编码
WebPPicture m_Picture;
WebPConfig m_Config;
GsRGBAType m_inputType;
if (!WebPPictureInit(&m_Picture) || !WebPConfigInit(&m_Config))
GS_E << "WEBP encode Error!";
//修改配置参数可以改变编码质量和文件大小,控制是否无损压缩, 但是引入这个webp 就是为了减小大小,
//建议在无文字的瓦片可以直接压缩默认, 有问题需要具体看效果
m_Config.method = 6;
m_Config.quality = 25;
//经过大概测试, 想要好的压缩效果而且能保证图像不失真, 以上两个参数只能选6 和 25或者50 . 其他参数普适性不高, 但是这是没考虑解压缩时间,仅仅从效果上看
m_Config.autofilter = 1;
m_Config.alpha_quality = 0;
m_Config.emulate_jpeg_size = 1;
//m_Config.thread_level = 2;
if (!WebPValidateConfig(&m_Config)) {
GS_E << "WebPValidateConfig Error!";
return ;
}
//只有argb和YUV直接选择,所有传入要更改颜色顺序, 但是颜色顺序为Picture.argb 为bgra才能转换成功
m_Picture.use_argb = 1;
m_Picture.width = w;
m_Picture.height = h;
m_Picture.argb_stride = w;
// 客户端回调,我们在这里面把压缩好的数据存到自己想存的地方
m_Picture.writer = &CustomWebPWriterFunction;
// m_ImageIO 自己定义想怎么定都可以, 比如文件流, 内存流,
m_Picture.custom_ptr = (void*)m_ImageIO;
if (!WebPPictureAlloc(&m_Picture)) {
GS_E << "WEBP Alloc memory Error!";
return false;
}
//这里pRow 和nLen 为 像素排列顺序为bgra的整个未编码图像内存
memcpy( (unsigned char*)(m_Picture.argb) , pRow, nLen);
WebPAuxStats stats;
m_Picture.stats = &stats;
if (!WebPEncode(&m_Config, &m_Picture))
{
GS_E<< "webp encoding error";
}
WebPPictureFree(&m_Picture);
编码回调
int CustomWebPWriterFunction(const uint8_t * data, size_t data_size, const WebPPicture * picture)
{
ImageIO* io = (ImageIO*)picture->custom_ptr;
return data_size ? ((int)io->Write(data, data_size)) : 1;
}
2: 解码:
// 假定 m_Buff 为 从webp文件读出来的整个二进制
WebPDecoderConfig config;
WebPDecBuffer* output_buffer = &config.output;
WebPBitstreamFeatures* bitstream = &config.input;
if (!WebPInitDecoderConfig(&config)) {
GS_E<<"WEBP Library version mismatch!\n";
return false;
}
output_buffer->colorspace = MODE_RGBA;
config.options.no_fancy_upsampling = 1;
config.options.bypass_filtering = 1;
config.options.use_threads = 1;
config.output.colorspace = MODE_RGBA;
VP8StatusCode status = VP8_STATUS_OK;
size_t data_size = 0;
status = WebPDecode(m_Buff, m_nLen, &config);
if (VP8_STATUS_OK != status)
return false;
if (buff) {
//已经获得解码后的像素
output_buffer->u.RGBA.rgba;
output_buffer->u.RGBA.size;
//释放内存
WebPFreeDecBuffer(output_buffer);
//获取宽高
w = output_buffer->width;
h = output_buffer->height;
}
return true;