opencv+webp

WebP,互联网一个新的图片格式

WebP是一个新的图片格式,它为在互联网上的图片提供了有损和无损压缩。WebP的无损图片比PNG的图片的大小小26%(研究结果)。在同等的SSIM(SSIM wiki)指数下,WebP的有损图片比用JPEG的图片大小小25-34%(研究结论)。WebP仅需要22%额外的字节(研究结果)就能支持无损透明度(alpha通道)。

网站管理员和Web开发者可以使用WebP图片格式来创建更小的和更丰富的图片来让你的web更快。

WebP是如何工作的?

WebP的有损压缩使用了预测编码(介绍)来编码图片,该方法也同样用于VP8视频编解码器压缩视频的关键帧。预测编码使用在相邻的块的像素值来预测一个块中的值,然后只编码的实际值和预测之间的差(剩余)。

这个差值通常包含很多0值,而这写可以更有效的被压缩。然后将差值通过通常的变换、量化、熵编码。WebP还采用了大小可变的块。

WebP的无损压缩用已经看到的图片帧来准确的重新构造新像素,如果发现没有很好的匹配,则使用一个本地的调色板,这个调色板不断更新,以重新使用最新的颜色。这种压缩模式被命名为“VP8L”,与所谓的LZ77(?)压缩算法拥有一些共同的特点。

一个WebP文件是包括VP8或者VP8L的图片数据,是给予RIFF的容器。libwebp库是一个参考WEBP规范实现的,并在此git仓库和一个压缩包。

WebP支持

很多种工具支持WebP,另外,Google Chrome原生支持它,Google Chrome Frame插件用来在IE,Opera 11.10和Android冰淇淋三明治上支持WebP。

开发者还支持各种图片编辑工具。此版本还提供了轻量级的编码和解码库,libwebp和命令行工具cwebp、dwebp可以将图片和webp格式之间相互转换。完整的源代码在下载页上。

webp简介

WebP (发音”weppy”),由google 2010年发布。是一种同时提供了有损压缩与无损压缩的图片文件格式,派生自图像编码格式VP8 。 是由Google购买On2Technologies后发展出来的格式,以BSD授权条款发布。

目前PC浏览器只有Chrome兼容webp,但移动设备都有兼容webp的方案。

 

webp优缺点

相比JPEG,这种格式可以把图片大小减少40%,而且前整个互联网的流量中有65%为图片。这意味如果Google让这种格式得到普及的话,你浏览网页的速度将大幅提升。

美中不足的是,WebP格式图像的编码时间“比JPEG格式图像长8倍”。

 

案例 

淘宝App大图jpg和webpp格式对比:

jpg图片:87.6k      http://gw2.alicdn.com/bao/uploaded/i2/T1sIPTFB8bXXXXXXXX_!!0-item_pic.jpg

webp图片:17.6k     http://gw2.alicdn.com/bao/uploaded/i2/T1sIPTFB8bXXXXXXXX_!!0-item_pic.jpg_640x640q90.jpg_.webp

 

参考资料 

Google developers webp官方文档 

百度百科-webp 

wikipedia-webp   

Google推出新的图片格式WebP,挑战JPEG,让互联网更快 

BSD协议 

谷歌WebP图像格式评测:压缩率显著提升 

webp 浏览器兼容大全 

webp for Android 

支持Android4.0以下webp的使用 

webp 

ios如何使用webp  

WebP iOS 示例应用 

实时压缩项目文档 

 WebP转换器下载

在Linux,Windows或Mac OS X下载预编译cwebp的转换工具,转换PNG和JPEG为WebP。


#include 
#include 
#include 
#include 
#include 
#include 
#include 

static const int CV_IMWRITE_WEBP_QUALITY = 64;

using namespace std;
using namespace cv;

struct webp_t{
	size_t quality;
	bool lossless;
};

bool write(const Mat& img, webp_t webp);



int main(int argc, char *argv[])
{
    std::string inf = "d:\\images.jpg";
    IplImage* source= cvLoadImage(inf.c_str(),1);
	IplImage * dst = NULL;
	dst = cvCreateImage(cvSize(800,600), source->depth, source->nChannels);    //构造目标图象	
	cvResize(source, dst, CV_INTER_AREA);                         //缩放源图像到目标图像
	Mat img = cv::cvarrToMat(dst, true);
	
	cvReleaseImage(&dst);
	cvReleaseImage(&source);

	int params1[3] = {0};
	params1[0] = CV_IMWRITE_JPEG_QUALITY; //jpeg质量参数
	params1[1] = 87; //质量参数

	cv::vector buf;
	cv::imencode(".jpg", img, buf, std::vector(params1, params1+2));

	Mat show = imdecode(Mat(buf),CV_LOAD_IMAGE_COLOR);



	
	webp_t webp;
	webp.lossless=false;
	webp.quality=80;

    write(show,webp);
   
    //cvReleaseImage(&img);
}



bool write(const Mat& img, webp_t webp)
{
    int channels = img.channels(), depth = img.depth();
    int width = img.cols, height = img.rows;

    const Mat *image = &img;
    Mat temp;
    size_t size = 0;

	bool comp_lossless = webp.lossless;

    int params[3] = {0};
	params[0] = CV_IMWRITE_WEBP_QUALITY; //jpeg质量参数
	params[1] = webp.quality; //质量参数

    uint8_t *out = NULL;

    if(depth != CV_8U)
    {
        return false;
    }

    if(channels == 1)
    {
        cvtColor(*image, temp, CV_GRAY2BGR);
        image = &temp;
        channels = 3;
    }
    else if (channels == 2)
    {
        return false;
    }

    if (comp_lossless)
    {
        if(channels == 3)
        {
            size = WebPEncodeLosslessBGR(image->data, width, height, (int)image->step, &out);
        }
        else if(channels == 4)
        {
            size = WebPEncodeLosslessBGRA(image->data, width, height, (int)image->step, &out);
        }
    }
    else
    {
        if(channels == 3)
        {
            size = WebPEncodeBGR(image->data, width, height, (int)image->step, webp.quality, &out);
        }
        else if(channels == 4)
        {
            size = WebPEncodeBGRA(image->data, width, height, (int)image->step, webp.quality, &out);
        }
    }
	
    if(size > 0)
    {
     
            FILE *fd = fopen("dis.webp", "wb");
            if(fd != NULL)
            {
                fwrite(out, size, sizeof(uint8_t), fd);
                fclose(fd); fd = NULL;
            }
       
    }

    if (out != NULL)
    {
        free(out);
        out = NULL;
    }

    return size > 0;
}


你可能感兴趣的:(opencv)