使用libwebp 库编解码图片

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;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值