精华内容
下载资源
问答
  • 动态WebP

    千次阅读 2017-12-01 14:08:28
    然而目前对于JPEG、PNG、GIF等常用图片格式的优化已几乎达到极致,因此Google于2010年提出了一种新的图片压缩格式 – WebP,给图片的优化提供了新的可能。WebP为网络图片提供了无损和有损压缩能力,同时在有损条件下...

    1.背景

    目前网络中图片仍然是占用流量较大的一部分,对于移动端更是如此,因此,如何在保证图片视觉不失真前提下缩小体积,对于节省带宽和电池电量十分重要。

    然而目前对于JPEG、PNG、GIF等常用图片格式的优化已几乎达到极致,因此Google于2010年提出了一种新的图片压缩格式 – WebP,给图片的优化提供了新的可能。

    WebP为网络图片提供了无损和有损压缩能力,同时在有损条件下支持透明通道。据官方实验显示:无损WebP相比PNG减少26%大小;有损WebP在相同的SSIM(Structural Similarity Index,结构相似性)下相比JPEG减少25%~34%的大小;有损WebP也支持透明通道,大小通常约为对应PNG的1/3。

    同时,谷歌于2014年提出了动态WebP,拓展WebP使其支持动图能力。动态WebP相比GIF支持更丰富的色彩,并且也占用更小空间,更适应移动网络的动图播放。

    目前国内外各大互联网公司已逐步使用WebP,科技博客GigaOM曾报道,YouTube的视频缩略图采用WebP后,网页加载速度提升了10%;谷歌网上应用商店采用WebP后,每天可节省几TB的带宽,页面平均加载时间大约减少1/3;谷歌移动应用市场采用WebP图片格式后,每天节省了50TB的存储空间;2014年腾讯新闻客户端应用了WebP后,流量峰值带宽降低9GB,网络连接延时不变的前提下,平均图片延时和数据下载延时降低了100ms;2014年空间装扮也全量转换成WebP,带宽上也有显著降低。(虽然听说目前已转成SharpP格式…)

    WebP的优势在于它具有更优的图像数据压缩算法,在拥有肉眼无法识别差异的图像质量前提下,带来更小的图片体积,同时具备了无损和有损的压缩模式、Alpha 透明以及动画的特性,在 JPEG 和 PNG 上的转化效果都非常优秀、稳定和统一。

    本文主要对WebP现状与原理进行整理,并尤其研究其动图格式在Android上的支持情况。

    2.原理

    WebP的压缩主要分为有损压缩、无损压缩以及有损带透明通道压缩。

    2.1 有损WebP

    有损WebP基于VP8视频编码中的预测编码方法来压缩图像数据,其基本步骤类似于JPEG压缩,主要包含格式转换、分割子块、预测编码、FDCT、量化、Z排列、熵编码,流程如下图所示,红色代表与JPEG不同的部分。

    1) 格式转换

    若压缩前图像数据为RGB格式,则需先进行格式转换成YUV格式,Y表示亮度分量,UV表示色度分量。之所以转换成YUV格式是因为人类视觉对亮度远比色度敏感,所以可通过适当减少色度数据的存储来节省数据占用的空间,但却不会对视觉效果造成太大影响,如可每两个或四个相邻的像素点才保存一对UV值。

    2) 分割宏块

    接下来将数据分割成一个个8x8或16x16的宏块。

    3) 预测编码

    预测编码的原理是基于前面编码好的宏块,预测多余的动作颜色等信息,属于帧内预测。对各宏块可使用以下几种帧内预测模式:

    • H_PRED(horizontal prediction).使用block左边的一列L来填充block中的每一列

    • V_PRED(vertical prediction):使用block上边的一行A来填充block中的每一行

    • DC_PRED(DC prediction):使用L和A中所有像素的平均值作为唯一的值填充block

    • TM_PRED(TrueMotion prediction):使用渐进的方式,记录上面一行的渐进差,以同样的差值,以L为基准拓展每一行。

    4) FDCT

    FDCT(Forward Discrete Cosine Transform,正向离散余弦变换)是将一组空间域的像素点转变成频域中的系数,对每个宏块执行FDCT,使得变换后数据的低频部分分布在数据块的左上方,高频部分集中在右下方,其中左上角第一个系数称为直流系数,其他均为交流系数。

    5) 量化

    量化是压缩中损失数据的主要步骤,它主要原理是把经过DCT变换后的宏块中每个数值除以量化表中对应的系数并取整。其中量化表中高频部分对应的系数比低频部分系数要大得多,则在经过量化后,高频部分的频率系数被大大衰减甚至许多被清零,而低频部分的频率系数则较好地被保留。由于人眼对低频部分更敏感,所以经过量化后再还原成图像对视觉效果影响较小,但数据得到有效的压缩。量化的最终目的是减少低频部分非零系数的幅值并增加高频部分零值系数的数量。

    6) Z排列

    为更便于后续的编码,需在编码前对数据块进行重新的排列,使得低频部分的数据排在前面,高频部分的数据排在后面,以增加数组中连续零值的数量,所以采用一种Z字型的排列方式。

    7) DPCM

    可用DPCM(Differential Pulse Code Modulation,差分脉冲编码调制)对直流系数进行编码。由于直流系数的数值较大,且相邻数据块的直流系数相差不大,所以可使用DPCM对相邻数据块间量化后的直流系数差值进行编码,从而提高压缩比。

    8) 行程编码

    行程编码是一种根据相同数据重复多次的情况简化表示的算法,例如1111222222333按照行程编码表示为(1,4)(2,6)(3,3)。由于量化后的交流系数中包含较多连续零值系数,因此可用行程编码对它们进行编码来有效压缩数据长度。

    9) 熵编码

    熵编码是一种无损数据压缩编码方式,WebP中采用布尔算术编码作为熵编码方式。和其它熵编码方法不同的地方在于,其他的熵编码方法通常是把输入的消息分割为符号,然后对每个符号进行编码,而算术编码是直接把整个输入的消息编码为一个数,一个满足(0.0 ≤ n < 1.0)的小数n。消息越长,编码表示它的间隔就越小,表示这一间隔所需的二进制位就越多。

    10) 其他

    WebP还有一些细节上的步骤,比如自适应分块(对不同区域的宏块分配不同的压缩参数)、环路滤波等。

    为什么有损WebP会比JPEG好?

    • 主要原因是预测编码。

    • 自适应分块也提供了较好表现。

    • 环路滤波在中、低比特率的情况下有较大帮助。

    • 算数编码相比霍夫曼增强了5%~10%的压缩能力。

    2.2 无损WebP

    无损WebP基于使用不同的技术对图像数据进行转换,包括:预测空间变换、色彩空间转换、使用调色板、多像素打包成一个像素、alpha值替换等技术。对于熵编码,则采用改进的LZ77-Huffman编码来紧凑稀疏值,它是一种对距离值的2D编码技术。

    2.3 有损WebP(支持透明)

    区别于有损WebP和无损WebP,这种编码允许对RGB频道的有损编码同时可对透明度频道进行无损编码。由于这种形式目前其他的格式还未能提供,所以目前需要使用透明度的话都会使用无损的PNG,导致大小膨胀。对于这类图片,WebP提供了较好的压缩效果。相比有损的WebP,添加透明通道只增加22%的大小。

    因此,将支持透明的PNG换成无损+支持透明的WEBP可以平均节省60%-70%大小,这个已经被一些含较多Icon的移动网站证明。

    (如:https://github.com/EverythingMe/webp-test#readme

    2.4 动态WebP

    动态WebP的原理与GIF和APNG原理类似,每一帧记录变化区域的坐标、长宽、播放延时等用于还原并播放。

    3.文件结构

    一个WebP文件表示一个静态图片或动画,并可选的包含透明度、色彩

    配置文件和元数据等。

    3.1 WebP文件首部

    RIFF:ASCII字符RIFF。

    File Size:文件大小,以字节为单位。

    WEBP:ASCII字符WEBP,标识这是WebP文件

    3.2 有损WebP简要文件格式

    这种文件格式支持有损编码,但不包含透明度以及其他拓展特性,可以被许多旧版本软件支持。

    VP8 chunk:

    Chunk Header:VP8块首部,定义了VP8比特流数据的大小,以及该帧VP8数据的长宽等信息。

    VP8 data:VP8比特流数据。

    VP8比特流格式的定义可参考rfc6386,主要定义了如何将图像数据转换成YUV格式。https://tools.ietf.org/html/rfc6386

    3.3无损WebP简要文件格式

    这种格式用在无损WebP编码(可选透明)并且不要求拓展特性时。需要注意的是,较旧的WebP软件可能不支持该格式。

    VP8L chunk:

    属性意义类似于有损WebP的简要格式,其中VP8L的定义可参考文档:

    https://chromium.googlesource.com/webm/libwebp/+/master/doc/webp-lossless-bitstream-spec.txt

    3.4 拓展格式

    拓展格式包括:

    • VP8X用于指明使用的特性
    • 可选的‘ICCP’用于色彩配置
    • 可选的‘ANIM’用于动画控制
    • 可选的‘EXIF’用于EXIF元数据
    • 可选的‘XMP’用于XMP元数据

    对于静态图像,图像数据包含一帧数据,由以下组成:

    • 一个可选的透明度子chunk
    • 1个比特流子chunk

    对于动态图像,图像数据则包含多帧数据。

    拓展头部格式:

    ICC profile(I):置位时表示包含ICC配置文件。

    Alpha(L):当图像包含透明数据时置位。

    EXIF metadata(E)当包含EXIF元数据时置位。

    XMP metadata(X):当包含XMP元数据时置位。

    Animation(A):动态WebP置位,此时ANIM和ANMF数据块中的数据将会被使用来控制动画。

    Canvas Width Minus One:画布的真实宽度是该数值+1。

    Canvas Height Minus One:画布的真实高度是该数值+1。

    动画

    WebP动画被ANIM和ANMF块所控制。

    ANIM Chunk:

    对于一个动图,该块数据定义了动画的全局参数。

    Background Color: 定义画布的背景颜色,以BGRA的顺序存储。这个颜色会被填充到每帧数据没用到的区域。

    LoopCount:循环次数,0表示无限循环。

    当动画标识被置位时,该数据块必须出现。当动画标识位没出现时,该数据块会被忽略。

    ANMF chunk:

    对于动图,该数据块包含了一帧图像的数据。

    Frame X:该帧数据左上角X坐标为该值*2。

    Frame Y:该帧数据左上角Y坐标为该值*2。

    Frame Duration: 播放该帧后的延时时间,以ms为单位。

    Blending method (B):标识如何混用前面画布的相应透明像素点。置0时,处理完前面一帧图像后,使用透明混合。置1时,不混合,渲染时直接覆盖矩形区域。

    Disposal method (D):标识该帧数据在被显示后如何处理画布。置0时不处理;置1时将画布矩形区域转换成ANIM定义的背景颜色。

    Frame Data:以2字节为单位,包含图像比特流数据以及可选的透明度数据。

    Alpha

    Pre-processing (P): 标识压缩中使用了预处理。

    Filtering method (F): 滤波方法。0-无过滤;1-横向过滤;2-垂直过滤;3-梯度过滤。

    Compression method (C): 0-无压缩;1-使用WebP无损格式压缩。

    Alpha bitstream:编码的透明度比特流数据

    颜色配置文件、元数据数据的文件格式类似,主要是头部ASCII码不同。

    3.5 文件布局示例

    带透明有损WebP文件形如:

    无损WebP形如:

    无损WebP包含ICC配置文件和XMP元数据形如:

    动态WebP包含EXIF元数据形如:

    4.与其他格式比较

    有损WebP vs JPEG:

    谷歌使用Lenna、Kodak、Tecnick还有Image_crawl四个图像来源来做实验,在相同或稍高的SSIM基础上,WebP相比JPEG体积降低25% ~ 34%。详见:

    https://developers.google.com/speed/webp/docs/webp_study

    无损WebP 、有损带透明WebP vs PNG

    下图是选取了1000张网络中的PNG,对其进行压缩后,与对应的无损WebP以及有损带透明WebP比较。可见绝大部分图片经过两种WebP压缩后均比PNG要小。

    WebP的编码时间较长,是PNG的5倍以上,但解码速度与PNG差不多,甚至很多时候比PNG快。而WebP在编码时占用内存比PNG高25%,解码时比PNG低30%。

    详见:https://developers.google.com/speed/webp/docs/webp_lossless_alpha_study

    动态WebP vs GIF

    优势:

    • WebP支持24位RGB和8位透明通道,GIF仅支持8位色彩及1位透明度。

    • WebP支持无损和有损两种模式,而且对于动态图,能同时结合有损和无损的图片。而GIF仅支持无损的压缩。WebP的有损压缩技术也更好地适应从现实世界视频中创建的动图。

    • WebP相比GIF占用更小的空间。Animated GIFs转换为有损WebP减少64%,转换成无损WebP减少19%,这对移动网络十分重要。

    • WebP使用更短的解码时间,WebP所用解码时间是GIF的57%。

    劣势:

    • 支持不够普遍。

    • 添加WebP支持到浏览器需要添加较多代码,但这在将来当WebP和WebM共享更多解码代码或者WebP被WebM合并后会有改善。

    动态WebP vs APNG

    APNG是一种基于PNG的编码,对动图的编码方式类似于WebP,都是对变化的区域进行编码。虽然理论上单张WebP要比PNG小,但有些整合成动图形式后WebP会比APNG更大:

    WEBP、APNG、GIF简要比较表格

    虽官方给出实验示例中无论静态或动态WebP都有比较好的压缩表现,但实际上,自己尝试用谷歌提供转换工具转换以及查询某些网站上的示例,都显示静态和动态WebP的压缩率均不太稳定,基于不同的图片压缩后的大小反而比JPEG或PNG更大。

    5.支持情况

    在浏览器上的支持:

    在终端上的支持:

    对于在App中使用WebP,除了Android 4.0以上提供了静态WebP原生支持外,其他版本和IOS都可以直接使用官方提供的解析库来支持静态WebP

    Android:https://github.com/alexey-pelykh/webp-android-backport

    iOS:https://github.com/carsonmcdonald/WebP-iOS-example

    然而,对于动态WebP,目前只能找到facebook的开源库Fresco对其支持,不过Fresco最低仅支持API 9,且引用的相关库较多。

    https://www.fresco-cn.org/

    6.总结

    WebP作为一种较新的图片格式,在一定程度上提高了图片的压缩率,但目前压缩表现尤其对于动图,还较不稳定。

    而Android对WebP动图支持较差,目前仅有Fresco一个开源库支持,要引入项目中,需进一步分离出无关的功能,并考虑最低仅支持API 9的问题。

    参考文献

    https://developers.google.com/speed/webp/ 
    http://www.jianshu.com/p/555859783f63 
    https://isparta.github.io/compare-webp/index_a.html#12 
    http://littlesvr.ca/apng/gif_apng_webp1.html 
    https://www.fresco-cn.org/

    展开全文
  • 动态图(三) 动态WebP解码与播放概述环境搭建工程libwebp解码播放GitHub 概述 WebP是谷歌定义的,如顾名思义(web picture),就是专门优化用于web显示的图片,大概就这样。 定义: 友(you)情(qiang)链接:...

    动态图(三) 动态WebP解码与播放

    概述

    WebP是谷歌定义的,如顾名思义(web picture),就是专门优化用于web显示的图片,大概就这样。
    定义:
    友(you)情(qiang)链接:https://developers.google.com/speed/webp/
    无(wu)情(qiang)链接:https://developers.google.cn/speed/webp?hl=zh-cn

    GitHub Mirror: https://github.com/webmproject/libwebp

    环境

    解码:libwebp
    显示:GDI+ + Win32
    开发环境: VS2015

    搭建工程

    libwebp
    1. Clone libwebp
    2. 用vs新建一个lib工程,名为 libwebp.vcxproj,把llibwebp\src\目录整个拷到工程目录,加入src*.*到工程去

    解码

    解码目标是使用libwebp把所有webp帧解析成BGRA流,用来构建后续用来显示的GDI+ Bitmap,部分代码:

    //WebP解码
    #include "stdafx.h"
    #include "WebPLoader.h"
    #include "StringUtil.hpp"
    
    BOOL CWebPLoader::LoadImage(const wstring& strImg)
    {
        //借用了 https://github.com/webmproject/libwebp/blob/master/examples/anim_util.h
        return ReadAnimatedImage(CStringUtil::ToStringA(strImg).c_str(), &image);
    }
    
    Bitmap* CWebPLoader::GetFrameAt(UINT32 nIndex, UINT32& nDelayMS)
    {
        if (nIndex >= image.num_frames)
            return m_pBmp;
    
        DecodedFrame* pFrame = &image.frames[nIndex];
        if (!pFrame->rgba)
            return m_pBmp;
    
        Bitmap* pBmp = m_pBmp ? m_pBmp : new Bitmap(image.canvas_width, image.canvas_height);
        BitmapData bmd;
        Rect rc(0, 0, image.canvas_width, image.canvas_height);
        pBmp->LockBits(&rc, ImageLockModeRead | ImageLockModeWrite, PixelFormat32bppARGB, &bmd);
        LPBYTE pDst = (LPBYTE)bmd.Scan0;
        LPBYTE pSrc = pFrame->rgba;
    
        int rowsize = rc.Width * 4;
        for (int h = 0; h < rc.Height; ++h)
        {
            memcpy(pDst, pSrc, rowsize);
            pSrc += rowsize;
            pDst += bmd.Stride;
        }
        pBmp->UnlockBits(&bmd);
        m_nCurFrame = nIndex;
        m_pBmp = pBmp;
        nDelayMS = pFrame->duration;
        return pBmp;
    }
    

    借用 https://github.com/webmproject/libwebp/blob/master/examples/anim_util.*,并作相应修改,部分代码:

    // Read animated WebP bitstream 'webp_data' into 'AnimatedImage' struct.
    static int ReadAnimatedWebP(const char filename[],
                                const WebPData* const webp_data,
                                AnimatedImage* const image) {
      int ok = 0;
      int dump_ok = 1;
      uint32_t frame_index = 0;
      int prev_frame_timestamp = 0;
      WebPAnimDecoder* dec;
      WebPAnimInfo anim_info;
    
      memset(image, 0, sizeof(*image));
    
      //
      //We need BGRA, so we can build gdi+ bitmap directly.
      WebPAnimDecoderOptions opt;
      memset(&opt, 0, sizeof(opt));
      opt.color_mode = MODE_BGRA;
      opt.use_threads = 0;
      dec = WebPAnimDecoderNew(webp_data, &opt);
      if (dec == NULL) {
        //WFPRINTF(stderr, "Error parsing image: %s\n", (const W_CHAR*)filename);
        goto End;
      }
    
      // Main object storing the configuration for advanced decoding
      WebPDecoderConfig decoder_config;
      // Initialize the configuration as empty
      // This function must always be called first, unless WebPGetFeatures() is to be called
      if (!WebPInitDecoderConfig(&decoder_config)) {
          goto End;
      }
    
      // Retrieve features from the bitstream
      // The bitstream structure is filled with information gathered from the bitstream
      int webp_status = WebPGetFeatures(webp_data->bytes, webp_data->size, &decoder_config.input);
      if (webp_status != VP8_STATUS_OK) {
          goto End;
      }
    
      if (!WebPAnimDecoderGetInfo(dec, &anim_info)) {
        fprintf(stderr, "Error getting global info about the animation\n");
        goto End;
      }
    
      // Animation properties.
      image->canvas_width = anim_info.canvas_width;
      image->canvas_height = anim_info.canvas_height;
      image->loop_count = anim_info.loop_count;
      image->bgcolor = anim_info.bgcolor;
    
      // Allocate frames.
      if (!AllocateFrames(image, anim_info.frame_count)) return 0;
    
      // Decode frames.
      while (WebPAnimDecoderHasMoreFrames(dec)) {
        DecodedFrame* curr_frame;
        uint8_t* curr_rgba;
        uint8_t* frame_rgba;
        int timestamp;
    
        if (!WebPAnimDecoderGetNext(dec, &frame_rgba, &timestamp)) {
          fprintf(stderr, "Error decoding frame #%u\n", frame_index);
          goto End;
        }
        assert(frame_index < anim_info.frame_count);
        curr_frame = &image->frames[frame_index];
        curr_rgba = curr_frame->rgba;
        curr_frame->duration = timestamp - prev_frame_timestamp;
        curr_frame->is_key_frame = 0;  // Unused.
        memcpy(curr_rgba, frame_rgba,
               image->canvas_width * kNumChannels * image->canvas_height);
        ++frame_index;
        prev_frame_timestamp = timestamp;
      }
      ok = dump_ok;
      if (ok) image->format = ANIM_WEBP;
    
     End:
      WebPAnimDecoderDelete(dec);
      return ok;
    }
    
    

    播放

    使用标准Win32工程模板,加个定时器驱动,so easy,部分代码:

    #include "stdafx.h"
    #include "WebPDemo.h"
    #include "GdiplusAutoStartup.hpp"
    #include "WebPLoader.h"
    
    // 全局变量: 
    CWebPLoader g_webpLoader;
    UINT32 g_nCurrentFrameID = 0;
    
    int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                         _In_opt_ HINSTANCE hPrevInstance,
                         _In_ LPWSTR    lpCmdLine,
                         _In_ int       nCmdShow)
    {
        UNREFERENCED_PARAMETER(hPrevInstance);
        UNREFERENCED_PARAMETER(lpCmdLine);
    
        // 解码
        GDIPLUS_AUTO_STARTUP;
        WCHAR szPath[MAX_PATH + 1];
        GetModuleFileName(NULL, szPath, _countof(szPath));
        PathRemoveFileSpec(szPath);
        PathAppend(szPath, L"\\..\\..\\..\\test\\rainbow_cat.webp");
        if (!g_webpLoader.LoadImage(szPath))
        {
            MessageBoxA(NULL, "Error decoding file! Aborting.\n", "Error", MB_ICONERROR|MB_OK);
            return 1;
        }
        
        //
        return 0;
    }
    
    
    //
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)
        {
        case WM_CREATE:
            //first frame
            SetTimer(hWnd, 1234, 500, NULL);
            break;
        case WM_PAINT:
            {
                PAINTSTRUCT ps;
                HDC hdc = BeginPaint(hWnd, &ps);
    
                // 绘图代码
                RECT rcWin;
                GetClientRect(hWnd, &rcWin);
                Rect rcBg(0, 0, rcWin.right - rcWin.left, rcWin.bottom - rcWin.top);
                
                // 双缓冲
                HDC hMemDC = ::CreateCompatibleDC(hdc);
                HBITMAP hBmpOffscreen = ::CreateCompatibleBitmap(hdc, rcBg.Width, rcBg.Height);
                HBITMAP hBmpOld = (HBITMAP)::SelectObject(hMemDC, hBmpOffscreen);
    
    
                Graphics gr(hMemDC);
                gr.Clear(0xFFFFFFFFu);
    
                UINT32 nDelayMS = 0;
                Bitmap* pBmp = g_webpLoader.GetFrameAt(g_nCurrentFrameID, nDelayMS);
                if (pBmp)
                {
    
                    Rect rc(0, 0, rcWin.right - rcWin.left, rcWin.bottom - rcWin.top);
                    rc.Offset((rc.Width - (INT)pBmp->GetWidth()) / 2, (rc.Height - (INT)pBmp->GetHeight()) / 2);
                    rc.Width = pBmp->GetWidth();
                    rc.Height = pBmp->GetHeight();
                    gr.DrawImage(pBmp, rc);
                }
    
                BitBlt(hdc, 0, 0, rcBg.Width, rcBg.Height, hMemDC, 0, 0, SRCCOPY);
                ::SelectObject(hMemDC, hBmpOld);
                DeleteObject(hBmpOffscreen);
                DeleteDC(hMemDC);
    
                EndPaint(hWnd, &ps);
    
                //next frame
                SetTimer(hWnd, 1234, nDelayMS, NULL);
            }
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        case WM_ERASEBKGND:
            return 1;
        case WM_TIMER:
            if (wParam == 1234)
            {
                g_nCurrentFrameID++;
                g_nCurrentFrameID %= g_webpLoader.GetFrameCount();
                RECT rc;
                GetClientRect(hWnd, &rc);
                InvalidateRect(hWnd, &rc, TRUE);
            }
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        return 0;
    }
    
    

    GitHub

    https://github.com/conn-public/vs-proj/tree/master/project/WebPDemo

    展开全文
  • 最近项目有缩减包体的任务,分析包体发现前阵子的新引入的动态webp特别大,没办法,只能压缩了,找UI竟然告诉我她不会,是产品传入某个软件弄的,打算自己下一个,发现用不了,只能自力更生了,搜来搜去,发现google...

    最近项目有缩减包体的任务,分析包体发现前阵子的新引入的动态webp特别大,没办法,只能压缩了,找UI竟然告诉我她不会,是产品传入某个软件弄的,打算自己下一个,发现用不了,只能自力更生了,搜来搜去,发现google有提供官方的webp转换工具。
    google 的webp支持网站:https://developers.google.com/speed/webp/(需要梯子)
    下载地址在这里:https://storage.googleapis.com/downloads.webmproject.org/releases/webp/index.html(不用梯子)

    下载自己系统对应版本后解压点开bin文件夹,可以看到有多种工具:

    返回根目录,打开ReadMe.txt,往下翻

    看到这一句:

    ‘img2webp’ can turn a sequence of input images (PNG, JPEG, …)into an animated WebP file.

    不禁想大喊一声:“万岁”。
    后面还有个使用例子:

    example: img2webp -loop 2 in0.png -lossy in1.jpg -d 80 in2.tiff -o out.webp

    以下讲解Windows的使用方法

    1. 配置环境变量:

    计算机-右键-系统属性-环境变量-系统变量-Path,将下载的webp工具解压后的bin目录加入Path环境变量:

    2.参照例子

    随意弄几张图片,打开命令行,cd切换到图片所在目录下,参照readme.txt的参数讲解,输入命令,如果环境变量配置成功,应该是会显示成功的。

    img2webp -loop 2 01.png -lossy 02.png -d 80 03.png -o out.webp
    


    这时候就可以到图片目录下打来动态图了,电脑上可以用浏览器打开webp。
    问题来了,我们的png序列可是有几十张上百张的啊,难道一张一张的往里敲图片名称,这当然是不行的。

    3.使用bat批处理脚本自动生成并执行转换命令

    @echo off
    setlocal enabledelayedexpansion
    :: 指定存放文件的目录(必须为英文目录,不能有空格)
    set SrcFolder=这里替换为图片的输入目录
    set DstFolder=这里替换为动态webp的输出目录
    set imgs= 
    for /f "delims=\" %%a in ('dir /b "%SrcFolder%\*.png*"') do (
      echo %%a
      set "imgs=!imgs!"%%a" "
    )
    echo %imgs%
    set /a loop = 0
    set /a time = 40
    set /a q = 65
    cd /d %SrcFolder%
    :: 执行命令
    img2webp -v -loop %loop% -lossy -q %q% -d %time%  %imgs% -o %DstFolder%\out_quality%q%_loop%loop%_frametime%time%.webp 
    img2webp -v -loop %loop% -lossless -d %time%  %imgs% -o %DstFolder%\out_lossless_loop%loop%_frametime%time%.webp 
    img2webp -v -loop %loop% -mixed -d %time%  %imgs% -o %DstFolder%\out_mixed_loop%loop%_frametime%time%.webp
    
    pause
    

    指定 图片的输入SrcFolder和输出目录DstFloder,保存为bat文件,点击运行即可装换成功。

    time 指定每帧的时间,也可以在每一个图片名称后分别进行控制
    loop 指定webp循环次数
    q 指定压缩质量,越高越好,生成文件也越大

    这里生成了三种版本的动态webp,分别是有损,无损,混合版本,你可以根据需求进行选择,一般使用mixed版本,生成动态webp大小质量都较为合适,不过webp可能是压缩算法的原因,小部分webp有时候无损反而占用更小空间,可以稍微注意一下。

    refer:https://blog.csdn.net/hjiangshujing/article/details/80522452

    展开全文
  • 几种 WebP 动态图制作方法

    千次阅读 2018-05-01 11:55:00
    目前唯一有图形用户界面的 动态 webp 编辑器,利用最新版本 libwebp v1.0.0生成的有损动态图是打不开.这个有两个版本, 推荐使用 2013.1, unstable 2016.1 版本无法打开有些动态 webp 文件.RealWorld Paint also ...

    1.RealWorld Paint

    目前唯一有图形用户界面的 动态 webp 编辑器, 利用最新版本 libwebp v1.0.0 生成的有损动态图是打不开.
    这个有两个版本, 推荐使用 2013.1, unstable 2016.1 版本无法打开有些动态 webp 文件.
    RealWorld Paint also supports many standard image files like .jpg, .png, .bmp, .gif, .webp and more.
    http://www.rw-designer.com/image-editor

    2.ffmpeg ( 编译时需要加 --enable-libwebp )
    ffmpeg 编码时两个参数说明
    -lossless boolean 启用/禁用无损模式 缺省值是0
    -qscale float 对于有损编码,这将控制图像质量,0到100.
    对于无损编码,这将控制更多压缩工作量和时间。缺省值为75.

    无损方式
    ffmpeg -i 00.mp4 -vf scale=240:-1 -r 10 -lossless 1 -loop 0 -y 00-lossless.webp

    有损方式
    ffmpeg -i 00.mp4 -vf scale=240:-1 -r 10 -qscale 90 -loop 0 -y 00-loss90.webp

    3.Animation conversion toolset
    命令方式的转换工具集.
    The web-ani-tools.zip package contains four separate tools for converting GIF, PNG and WebP animations.
    gif2webp - GIF -> WebP conversion.
    gif2apng - GIF -> animated PNG conversion.
    webp2apng - WebP -> animated PNG conversion.
    webp2gif - WebP -> GIF conversion.
    apng2webp - anmated PNG -> WebP conversion.
    apng2gif - anmated PNG -> GIF conversion.
    http://www.rw-designer.com/animation-tools

    4.libwebp
    library to encode and decode images in WebP format.
    命令方式, 目前最新发布 v1.0.0, 开源代码
    有编码 解码 查看等命令.
    https://github.com/webmproject/libwebp

    在这里可下载编译好的可执行程序

    http://downloads.webmproject.org/releases/webp/index.html

    下面是静态编译的无边框模式查看工具, 按住鼠标左键可以移动, 单击鼠标中键退出.

    https://github.com/qq2225936589/vwebp/raw/master/vwebp.exe

    备注: 动态 WebP 图片 Chrome 版本32+ 才支持.

    WebP qscale 90 602K                                                      GIF 741K

    转载于:https://www.cnblogs.com/nlsoft/p/8975942.html

    展开全文
  • webp制作工具Python源码

    2017-03-26 18:07:36
    利用google提供的webp工具包制作的GUI程序,包括png转webp,静态webp转动态webp等功能。
  • 利用google提供的webp工具包制作的GUI程序,包括png转webp,静态webp转动态webp等功能。
  • webp制作GUI程序for mac

    2017-03-26 17:53:08
    利用google提供的webp工具包制作的GUI程序,包括png转webp,静态webp转动态webp等功能。
  • iOS中显示WEBP动态图像

    千次阅读 2016-09-08 10:38:54
    webp iOS
  • 目前并非所有浏览器都能支持Webp图片,如果图片在HTML中,可以通过JS去进行判断,但是CSS中的图片无法通过JS去判断,通过此插件,可以自动生成Webp图片版的CSS,并且自动将是否支持Webp的判断语法插入到对应的HTML中
  • 该存储库包含一个Windows运行时组件,该组件包装了并允许对静态和动态WEBP图像进行解码。 该代码在MIT / X11下发布,因此可以随时进行修改并与世界分享您的更改。 如何 您可以使用WebPImage.DecodeFromByteArray...
  • webp-imageio-动态库.rar

    2020-04-02 09:14:10
    将图片转为webp格式,高保真压缩 项目可以直接用 包括windows 和linux系统动态动态库配置,环境配置网上有很多
  • 谷歌webp插件包下载地址,谷歌的需要翻墙,我翻墙给小伙伴们下载好了,这里只准备了3大系统的64位的,32位的取官网下载。 64:https://pan.baidu.com/s/1g_0jBUm6MYBd4DjxXbkx1g 32:...
  • Glide支持webp扩展

    千次阅读 2017-07-21 19:03:12
    Glide的gif加载性能比fresco要好,但是Glide并不支持动态的webp,取舍后决定用fresco的webp库扩展Glide,让Glide也支持动态webp。 Glide的框架十分优秀,能简单的进行扩展,有时间会写一下Glide源码解读的文章。 ...
  • WebP图片制作GUI工具

    千次阅读 2017-03-27 11:37:56
    动态webp比gif好了不止一两点,gif只支持2位的透明通道,而且图片锯齿严重。OK,既然有这么牛逼的图片格式,我们当然要好好使用了,而且现在Android端有Facebook推出的Fresco框架完美支持,不
  • WebP

    2016-07-20 12:07:09
    了解完静态 WebP,下面再了解一下动态 WebP(Animated WebP):2013 年 11 月 21 日,Animated WebP 终于取得进展,并在 Chrome32 Beta 中得到了支持。目前 Animated WebP 支持将 GIF 直接转换成 Animated WebP,...
  • webp.rar 自动化转图片

    2019-11-20 23:00:31
    最近项目有缩减包体的任务,分析包体发现前阵子的新引入的动态webp特别大,没办法,只能压缩了,找UI竟然告诉我她不会,是产品传入某个软件弄的,打算自己下一个,发现用不了,只能自力更生了,搜来搜去,发现google...
  • 这是基于Golang的服务器,可让您即时提供WebP图像。默认情况下,它将转换jpg,jpeg,png文件,可以通过编辑config.json对其进行自定义。 当前支持的图像格式:JPEG,PNG,BMP,GIF(目前为静态图像) 例如,当您访问...
  • WebP介绍

    2021-06-03 16:43:33
    关于WebP WebP,是一种支持有损压缩和无损压缩的图片文件格式,派生自图像编码格式 VP8。根据 Google 的测试,无损压缩后的 WebP 比 PNG 文件少了 45% 的文件大小,即使这些 PNG 文件经过其他压缩工具压缩之后,...
  • Webp动态图的加载
  • 译文地址:http://deanhume.com/Home/BlogPost/service-workers--dynamic-responsive-images-using-webp-images/10132/图片在如今的站点上不可或缺。试想一下,在我们网页上没有图片会怎样?高质量的图片能够使你的...
  • 主要利用Imazen.WebP.dll来生成Webp格式图片 namespace Melon.AspNet.Base.Handler { /// <summary> /// 图片路径格式:{域名}/原始文件或{域名}/原始文件_{指定大小}或{域名}/原始文件_...
  • webp 初探

    2014-11-10 11:08:00
    WebP是Google新推出的影像技术,它可让...但webp也有一定的局限性,目前主流的浏览器只有Chrome和opera 支持,因此实现的时候需要前端根据用户的浏览器类型来动态匹配图片类型。 文件转换方案 推荐3种不同的转换方...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,410
精华内容 3,364
关键字:

动态webp