使用ffmpeg进行webp图片压缩,ffmpeg的帮助信息查看方法
01.ffmpeg中帮助信息的查看
? ffmpeg继承了很多编解码器,使用ffmpeg很多时候需要了解这些编解码器的参数。
? 最近在看小泉同学的bd,去网络上搜寻op的cd资源的时候,下载下来发现一张扫图有80mb大小。音乐本身是hires压制的flac,大小是qq音乐上无损flac的3倍。一首歌占100mb的空间,这应该是hires的音乐的正常大小了。
? 因为hi-res是96kHz是通常采样的两倍,采样位数也更高,通常的cd音质是 44.1kHz 16bit的音源,而hi-res通常是 96kHz 24bit,如果音源一样的话 应该大约是 (96/44.1) * (24/16)=3.27倍大小。这是算是验证了,一般一首正常长度的歌,一般的flac是30多mb,而hi-res 是100mb左右。
? 但是扫图的大小感觉过大了,图像的分辨率是7623*3763,已经超过屏幕的大小,主要是cd封面大小的一张图占用80mb实在是浪费,于是想用目前流行webp格式进行压缩。
? 执行
? 给定后缀名,ffmpeg会自动寻找编码器进行处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ffmpeg.exe -i . 1.png out.webp ffmpeg version N-93851-gdcc999819d Copyright (c) 2000-2019 the FFmpeg developers built with gcc 8.3.1 (GCC) 20190414 configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt libavutil 56. 27.100 / 56. 27.100 libavcodec 58. 52.101 / 58. 52.101 libavformat 58. 27.103 / 58. 27.103 libavdevice 58. 7.100 / 58. 7.100 libavfilter 7. 51.100 / 7. 51.100 libswscale 5. 4.101 / 5. 4.101 libswresample 3. 4.100 / 3. 4.100 libpostproc 55. 4.100 / 55. 4.100 [png_pipe @ 000001b495fa8f40] Stream #0: not enough frames to estimate rate; consider increasing probesize Input #0, png_pipe, from '. 1.png': Duration: N/A, bitrate: N/A Stream #0:0: Video: png, rgb24(pc), 7623x3763 [SAR 31496:31496 DAR 7623:3763], 25 tbr, 25 tbn, 25 tbc Stream mapping: Stream #0:0 -> #0:0 (png (native) -> webp (libwebp)) Press [q] to stop, [?] for help Output #0, webp, to 'out.webp': Metadata: encoder : Lavf58.27.103 Stream #0:0: Video: webp (libwebp), bgra, 7623x3763 [SAR 1:1 DAR 7623:3763], q=2-31, 200 kb/s, 25 fps, 1k tbn, 25 tbc Metadata: encoder : Lavc58.52.101 libwebp [libwebp @ 000001b495fbcdc0] Using libwebp for RGB-to-YUV conversion. You may want to consider passing in YUV instead for lossy encoding. frame= 1 fps=0.1 q=-0.0 Lsize= 9820kB time=00:00:00.00 bitrate=80448240.0kbits/s speed=7.85e-05x video:9820kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000000% |
看到这一行, Stream #0:0 -> #0:0 (png (native) -> webp (libwebp)),ffmpeg使用了一个libwebp的编码器进行压缩。
所以这里我们就要查一下libwebp这个编码器具体有哪些参数。
?
下面是ffmpeg查看帮助文档的方法
基础的帮助 | 选中的项目的帮助 |
---|---|
ffmpeg -? or ffmpeg -h | ffmpeg -h decoder=decoder_name |
额外的帮助/扩展的帮助 | ffmpeg -h encoder=encoder_name |
ffmpeg -h long or ffmpeg -h full | ffmpeg -h demuxer=demuxer_name |
ffmpeg –? topic or ffmpeg -h topic | ffmpeg -h muxer=muxer_name |
这里我们执行以下命令即可
02.libwebp的使用
查看libwebp的帮助如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | ffmpeg -h encoder=libwebp ffmpeg version N-93851-gdcc999819d Copyright (c) 2000-2019 the FFmpeg developers built with gcc 8.3.1 (GCC) 20190414 configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt libavutil 56. 27.100 / 56. 27.100 libavcodec 58. 52.101 / 58. 52.101 libavformat 58. 27.103 / 58. 27.103 libavdevice 58. 7.100 / 58. 7.100 libavfilter 7. 51.100 / 7. 51.100 libswscale 5. 4.101 / 5. 4.101 libswresample 3. 4.100 / 3. 4.100 libpostproc 55. 4.100 / 55. 4.100 Encoder libwebp [libwebp WebP image]: General capabilities: none Threading capabilities: none Supported pixel formats: bgra yuv420p yuva420p libwebp AVOptions: -lossless <int> E..V..... Use lossless mode (from 0 to 1) (default 0) -preset <int> E..V..... Configuration preset (from -1 to 5) (default none) none E..V..... do not use a preset default E..V..... default preset picture E..V..... digital picture, like portrait, inner shot photo E..V..... outdoor photograph, with natural lighting drawing E..V..... hand or line drawing, with high-contrast details icon E..V..... small-sized colorful images text E..V..... text-like -cr_threshold <int> E..V..... Conditional replenishment threshold (from 0 to INT_MAX) (default 0) -cr_size <int> E..V..... Conditional replenishment block size (from 0 to 256) (default 16) -quality <float> E..V..... Quality (from 0 to 100) (default 75) |
我们发现有以下的选项
-lossless 是设置无损压缩
-preset 是几个预设的参数
-quality 这个就是主要的参数了,控制压缩率
-cr_size 这个参数试了一下 200和16各压了一遍,没看出什么区别,大小也一样
不设置参数默认压制出来 的图片 80mb 变成10mb左右,这已经是接近无损的质量了。
测试了一下 quality 0的时候也有500多kb大小,但是图片就有点糊了。
去网上查了一下libwebp参数的具体设置,有人得出了下面的结论
https://www.cnblogs.com/yanguhung/p/10784598.html
1 2 3 4 5 6 7 8 9 | 选择无损压缩时,“-lossless -q 100” 是最佳方案,注意:cwebp 仅仅对png格式的图片使用无损压缩时,会有较为高效的压缩率和图片质量 选择有损压缩时,“-q 75”是最佳方案(图片质量与体积大小达到均衡)建议其他格式图片使用有损压缩 无论何种压缩参数,加上“-m 6”都能使得输出的 WebP 图片进一步减少体积,量级是1%~2%,但是会增加耗时 非png格式的图片选择无损压缩时,“-lossless -q 100” 时编码时间长,图片质量反而极高可能变大,编码时间时间很长,cpu使用率飙升跑满,不建议使用 建议选择有损压缩时,“-q 75”是最佳方案(图片质量与体积大小达到均衡)建议使用 |
还有webp 和jpg的对比
1 | 即使jpg图片同比例压缩为jpg和webp图片 webp图片也要比jpg图片质量低百分之10~20之间 |
也就是说,webp的压缩率完全优于jpg,但是webp的编码时间比jpg长8倍。
所以说我们使用的时候按照默认参数来就行了。
调整图片大小用-vf scale=iw/3:ih/3,可以指定和原来的比例,也可以指定明确的像素值比如1280:720.
单纯调整图片大小,无损压缩把图片宽高缩小3倍iw/3:ih/3,大小就只有5mb了。
但是这里不缩小大小,只压缩,所以按照默认参数就行。
1 | ffmpeg.exe -i input.png -vf scale=iw:ih -codec libwebp -lossless 0 -quality 75 out.webp |
编写一个压缩指定大小png图片的powershell脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | <# .synopsis 批量转换占用空间过大的图片 .example 使用方法如下 allPngtoWebp.ps1 -limitSize 10mb -paramStr '-codec libwebp -vf scale=iw/4:ih/4 -lossless 1 -quality 100' #> param( # 需要压缩的图片阈值大小,小于这个数值的图片不进行压缩 [int]$limitSize=10mb, [string]$paramStr='-vf scale=iw:ih -codec libwebp -lossless 0 -quality 75' ) #只压缩png格式的图片,先检索目录下的png图片 $count=0 Get-ChildItem -Recurse *.png | foreach{ if($_.Length -gt $limitSize){ Write-Host -ForegroundColor Green "detect large png picture : $($_.FullName) size:$($_.Length/1mb) " $newfullname=$_.FullName.Substring(0,$_.FullName.Length-4)+'.webp' Invoke-Expression "ffmpeg.exe -i '$($_.FullName)' $paramStr '$($newfullname)'" # ffmpeg.exe -i $_.FullName $paramStr ($_.FullName.Substring(0,$_.FullName.Length-4)+'.webp') if (Test-Path -Path $newfullname){ rm $_.FullName Write-Host -ForegroundColor yellow "delete $($_.FullName) complete " $count++ } else{ Write-Host -ForegroundColor red "convert failed " break } } } Write-Host -ForegroundColor Green "compress $count png files complete" |