技术经验谈 技术经验谈
首页
  • 最佳实践

    • 抓包
    • 数据库操作
  • ui

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 总纲
  • 整体开发框架
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

hss01248

一号线程序员
首页
  • 最佳实践

    • 抓包
    • 数据库操作
  • ui

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 总纲
  • 整体开发框架
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 前端

  • 图形图像

    • 像素操作
    • 图床的选择
    • 图片压缩
    • 图片压缩2
    • 最新图像压缩格式AVIF
    • 颜色模型和色彩空间
    • webP压缩
      • 浏览器/webview
      • Android
        • webp的exif编辑bug
        • 版本 1.3.5
        • Android上如何支持下方的压缩参数?
      • 修改图片尺寸时,目标图片分辨率的选择:
      • 对png图片的损耗
      • Animated WebP的兼容性和动态图方案
        • 动效图方案:
        • 2022 年 Web 端主流动画实现方案:
      • Android
      • 各云存储/cdn图片处理的支持
        • 腾讯云
        • 阿里云
        • 七牛
      • Android-bitmap编解码
      • java imageIO
      • js-web
      • flutter
      • web网址
      • cli版本
        • npm
        • picgo插件
      • java imageIO
      • sejda-pdf/webp-imageio[#](https://www.cnblogs.com/xiyu714/p/14488900.html#2824252732)
      • 调用 gif2webp[#](https://www.cnblogs.com/xiyu714/p/14488900.html#3858267928)
        • 封装比较完善的库:
        • 测试
        • gif转webp
      • webp文件元信息的获取
        • 判断是否为动图,是否有透明通道
      • webp的exif支持
        • metadata-extractor是否支持?
        • groupdocs
        • exiftool是否支持?
      • java 里对jpg exif的读写的库
    • google相机拍照携带1s视频的实现和解析
  • 基础

  • 多媒体

  • 大数据风控

  • 大观

  • 技术视野

  • 云服务器价格对比
  • 其他IT相关
  • 图形图像
hss01248
2022-12-19
目录

webP压缩

# webp压缩

# 优越性

本节内容主要来自: Web图片优化(一):压缩方案简介 (opens new window)

WebP 对大多数图片有着更好的压缩率和图片质量。这里有一个把图片压到相同的质量下,以 JPG 为基准,WebP 和 AVIF 图片体积的对比:

AVIF and WebP vs JPEG

可以看到 WebP 的体积通常比 JPG 小30%,所以给图片转码个 WebP 作为渐进增强是十分有价值的。

下面那 2.7% 负优化情况在本文后面会有讲解。

# 对比:AVIF # (opens new window)

AVIF 是 AV1 视频编码对应的图片格式,AV1(对应VP10) 是 VP8 的下两代,AVIF 也就成为了 WebP 的继任者,它拥有比 WebP 更高的压缩率和更好的质量。

在上面的对比图里 AVIF 压缩率比 WebP 高了 20%,而且没有负优化的情况。

# 兼容性(2023.01)

https://caniuse.com/?search=a%27vi%27f

image-20230104112727899

因为比较新,兼容性上自然没有 WebP 那么乐观,Chrome 和 Firefox 都提供了支持;套壳浏览器 Edge 使用的是 Chrome 的内核所以也会支持的;苹果同样是 Alliance for Open Media (opens new window) 的成员,Safari 的支持只是时间问题。可以肯定的是 AVIF 将成为下一个被广泛使用的图片编码。

不过目前 AVIF 的生态还未成型,Netflix 等大厂支持 AV1 也都是今年才开始的。在写本文时 AVIF 正迎来一个爆发期,各种评测层出不穷,可见其受欢迎的程度。

不过本站目前没有使用 AVIF 图,不是我不想用,而是在测试时出现了一些问题:

  • 编码太慢,比 WebP 慢了 20 倍不止,还是先等等优化再说。尤其是一千万以上像素的大图,编解码几秒到十几秒,完全无法忍受
  • 压缩率不理想,在测试中全部155张图里只有极个别压缩率和质量超过 WebP,大部分体积反而比 WebP 大了好几倍。当然我还没有研究 AVIF 的转换参数,不知道 Netfilx 他们是用得什么参,也没有找到调优方面的文章。

# 兼容性-2022

# 浏览器/webview

https://caniuse.com/?search=Webp

如下图: 解码几乎全部支持: 97.3%,编码支持性一般: 77.79%

image-20221219111656145

Js api对webp的支持一般, 比如下方的 webp编码的api(使用canvas api将图片转换/压缩成webp)

image-20221219111825725

# Android

Android 4.0 以下不支持 WebP 图片格式 ; ( 不能使用 )

Android 4.0 以上支持 不带透明度 并且是 无损压缩 的 WebP 图片 ; ( 有限度的使用 , 不带透明度的图片 , 压缩量有限)

Android 4.2.1 以上的系统 , 支持 有损压缩 , 带透明度 的 WebP 图片 ; ( 完全支持 WebP 格式图片 )

也就是说 , 只有 4.2.1 4.2.14.2.1 以上的系统 , 才完全支持 WebP 图片格式 ;

现在基本上开发时设置的最小兼容版本都是 4.3 , 可以完全兼容 WebP 格式图片 ;

质量相同情况下,WebP 格式图像的体积要比 JPEG 格式图像小 40%,但 WebP 格式图像的编码时间比 JPEG 格式图像长 8 倍

# webp的exif编辑bug

https://developer.android.com/jetpack/androidx/releases/exifinterface

implementation "androidx.exifinterface:exifinterface:1.3.5"
1

# 版本 1.3.5

2022 年 10 月 24 日

发布了 androidx.exifinterface:exifinterface:1.3.5。版本 1.3.5 中包含这些提交内容 (opens new window)。

bug 修复

  • 修复了 saveAttributes() 产生无效 WebP 文件的两种情况。

经验证,确实解决了这个bug

# Android上如何支持下方的压缩参数?

不支持设置-sharp_yuv,但设置quality=100等效于-lossless

bool compress (Bitmap.CompressFormat format, int quality, OutputStream outputStream)
1

对于webp来说,quality要么是75,要么是100, 不要设其他的值.

截带文本的屏,推荐用无损(100), 即使同样是无损,webp的无损也要比jpg的无损(质量100)文件体积小很多. 如下图:

image-20221219155403051

如果使用有损webp,那么文字亮度明显变暗,被周围像素混淆

image-20221219155337732

更加明显的是这张代码截图

有损webp压缩

image-20221219155540387

无损webp压缩

image-20221219155604952

其他拍照,视频截图,用75即可

综合策略:

  • 如果一张图是png,或者质量为100的jpg,以及通过exif识别非相机拍照的照片:

    那么压缩时同时压缩一份无损webp和有损webp(质量75), 谁小用谁. 注意无损webp压缩会比较耗时,要几秒.

  • 如果是质量小于100的jpg,那么使用webp有损压缩,质量75.

各种截图软件的输出应设置为png输出,picgo压缩使用上述策略.

# 压缩参数选择和优化

(opens new window)

Web图片优化(一):压缩方案简介 (opens new window)

Web图片优化(二):WebP 参数分析 (opens new window)

美图图像选型评测及优化历程 (opens new window)

-q 75
-m 5
-sharp_yuv
1
2
3

当一张图上传后,如果是PNG(JPG 很少出现此问题)则同时使用有损和无损两种模式压缩,然后选择体积小的一个

推荐流程

# 修改图片尺寸时,目标图片分辨率的选择:

最好是16*16的倍数

Google最新的图片格式WEBP全面解析 (opens new window)

image-20221219111232156

# 一些不足

# 对png图片的损耗

WebP的质量损失

WebP 压缩后的图片甚至能比原图还大,在官网上也有对此的描述:can_a_webp_image_grow_larger_than_its_source_image (opens new window)

WebP两种压缩对比

左边的是有损模式,可以看到红色的字符串、紫色的关键字、以及绿色的注释部分都有色彩失真,而且文件体积是无损模式的7倍。有损压缩我还加了-sharp_yuv参数的,要是没这个参数那简直没法看。

你可以自己尝试一下,把 这张图 (opens new window) 上传到 squoosh (opens new window) 并选择 WebP Compress,看看它是怎么把你的图压成一坨屎的。

因为有这些问题,所以不能无脑把所有图片全用 cwebp 默认参数直接压。

那么怎么解决呢,目前我的方案是根据文件体积增加这一特征来检测。当一张图上传后,如果是PNG(JPG 很少出现此问题)则同时使用有损和无损两种模式压缩,然后选择体积小的一个。

这样无论是插画还是文字都能很好地处理,但如果遇到混合的那就无效了,不过这种情况应该很少。

# Animated WebP的兼容性和动态图方案

# 动效图方案 (opens new window):

建议的解决方案排序是 PAG>VAP>Lottie>WebP/APNG...,例如在 iOS 平台,所有的 PAG 文件播放都有比较不错的体验,因此我们更建议使用 PAG 交付,而在 Android 端 WebP 的稳定性更好,因此在 Android 更建议使用 WebP,当然在 Web 端依然可以使用 Lottie、WebP 作为平替。

# 2022 年 Web 端主流动画实现方案 (opens new window):

动态图片开发成本低,但是动态图片无法交互;

帧动画控制性一般,开发成本一般。但图片体积和动画帧数成正比,无法做到帧间压缩;

属性动画控制性高,开发成本随动画复杂度成正比;

使用动画 SDK 可以做到动画效果的极致还原,前端开发动画成本低,可操控性非常高,素材体积低。

image-20221219112603545

image-20221219112629795

# 一些测试案例

png压缩为webp的测试-表情图 (opens new window)

gif压缩为webp的测试 (opens new window)

WebP 转换的示例链接-又拍云 (opens new window)

# 应用

# Android

  • apk文件瘦身: booster插件-webp图片压缩 (opens new window)

  • 图片缓存库的本地缓存文件瘦身 : glide onResourceReady回调里把图片压缩成webp并覆盖原文件--> 直接开一个fileObserver线程,监听glide和fresco缓存文件夹的文件变化,有新创建的文件,就压缩成webp

# 各云存储/cdn图片处理的支持

# 腾讯云

图片压缩概述 (opens new window)

image-20221219163446445

# 阿里云

新版图片处理指南 (opens new window)

# 七牛

  • 七牛提供了高级图像处理的功能
  • 通过URL后拼接参数,能把gif图处理成webp
  • 1.安卓下七牛CDN借用高级图像处理功能form成webp(IOS维持GIF图原样)
  • 2.JS判断是否支持webp如果支持,把gif图通过七牛处理成webp动态图,不支持维持原样。
  • HTML5标签 picture,是一套精简的兼容方案,浏览器兼容可通过此标签来展示对应的图片
<picture>
  <source srcset="https://dn-odum9helk.qbox.me/test.gif?imageMogr2/thumbnail/100x|imageMogr2/format/webp" type="image/webp" />
  <img src="https://dn-odum9helk.qbox.me/test.gif?imageMogr2/thumbnail/100x" alt="MDN" />
</picture>
1
2
3
4

# 各语言/系统对图片压缩格式的支持

# Android-bitmap编解码

4.4以上, 全系列支持

https://github.com/hss01248/jpegQuality JAVA 计算jpg质量因子, Android和JAVA后台均可用

https://github.com/skyNet2017/Luban : Android

# java imageIO

https://github.com/coobird/thumbnailator java图片压缩工具,仅对imageIO的API封装

要支持webp读写,需要给ImageIO加插件:

比如

https://github.com/haraldk/TwelveMonkeys 只支持读/解码,不支持webp编码

https://github.com/nintha/webp-imageio-core 还需要自己编译,麻烦

https://github.com/sejda-pdf/webp-imageio 原生库打包好了到mavencentral---推荐

https://github.com/umjammer/vavi-image-webp 比较新

# js-web

纯浏览器端图片压缩,需要基于canvas api, 对webp的支持只有78%,

需要兼容处理: 如果不支持webp输出,则压缩为png或jpg.

以下的库用于生产均需要做兼容处理

https://github.com/alextanhongpin/compress.js 主要是输出为jpg

  • When working with image/gif, the compressed image will no longer animate.
  • When working with image/png with transparent background, the compressed image will lose transparency and result in black background.

https://github.com/brunobar79/J-I-C To compress the image, first it converts an image object to canvas and then compress it with the canvas method toDataURL(mimetype, quality), toDataURL对webp支持一般(编码)

https://github.com/idiotWu/canvas-compress 同上,对webp输出的支持一般.

# nodejs

https://github.com/imagemin/imagemin

https://github.com/imagemin/imagemin-webp

# flutter

https://pub.dev/packages/flutter_image_compress flutter图片压缩-Android/ios

https://pub.dev/packages/image_compression 另一个纯dart图片压缩库

https://pub.dev/packages/flutter_luban 纯dart,支持除web外所有平台

image_compression_flutter (opens new window) Combining use of packages :

  • image_compression (opens new window) : MacOS, Windows, Linux and Web
  • flutter_image_compress (opens new window) : Android and iOS

# squoosh-图片压缩对比工具

by google

# web网址

https://squoosh.app/

# cli版本

Node js

https://yjyj.net/learn/6261.html

# npm

https://www.npmjs.com/package/unplugin-imagemin

# picgo插件

https://www.npmjs.com/package/picgo-plugin-squoosh

# java webp相关解决方案

# java imageIO

https://github.com/coobird/thumbnailator java图片压缩工具,仅对imageIO的API封装

要支持webp读写,需要给ImageIO加插件:

比如

https://github.com/haraldk/TwelveMonkeys 只支持读/解码,不支持webp编码

https://github.com/nintha/webp-imageio-core 还需要自己编译,麻烦

https://github.com/sejda-pdf/webp-imageio 原生库打包好了到mavencentral---推荐

https://github.com/umjammer/vavi-image-webp 比较新

# sejda-pdf/webp-imageio# (opens new window)

在Java中,可以使用这个库:sejda-pdf/webp-imageio: Java ImageIO WebP support (opens new window) 其封装了多个系统的libwebp库版本,可以在Linux、Mac、Windows中使用,同时还发布在了Maven中。 但有一个问题,就是这个库,不能将GIF图片转为动态的webp文件。只会将GIF图片第一帧转为webp文件,也就是一张静态的图片。

// Obtain a WebP ImageReader instance
ImageReader reader = ImageIO.getImageReadersByMIMEType("image/webp").next();

// Configure decoding parameters
WebPReadParam readParam = new WebPReadParam();
readParam.setBypassFiltering(true);

// Configure the input on the ImageReader
reader.setInput(new FileImageInputStream(new File("input.webp")));

// Decode the image
BufferedImage image = reader.read(0, readParam);
1
2
3
4
5
6
7
8
9
10
11
12

GIF转webP动画的Java库:

# 调用 gif2webp# (opens new window)

gif2webp (opens new window) 是Google提供的sdk中的一个可执行工具,使用起来也很简单。

Copygif2webp.exe .\gif.gif -o gif.webp
1

# 封装比较完善的库:

https://sksamuel.github.io/scrimage/webp/

<!-- https://mvnrepository.com/artifact/com.sksamuel.scrimage/scrimage-core -->
        <dependency>
            <groupId>com.sksamuel.scrimage</groupId>
            <artifactId>scrimage-core</artifactId>
            <version>4.0.32</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.sksamuel.scrimage/scrimage-webp -->
        <dependency>
            <groupId>com.sksamuel.scrimage</groupId>
            <artifactId>scrimage-webp</artifactId>
            <version>4.0.32</version>
1
2
3
4
5
6
7
8
9
10
11

代码

 public static File toWebP(String path) throws Exception{
        long start = System.currentTimeMillis();
        File file = new File(path);
        ImmutableImage image = ImmutableImage.loader().fromFile(file);

        String name = file.getName().substring(0,file.getName().lastIndexOf(".")+1)+"webp";
        File newPath = new File(file.getParent(),name);

        Path output = image.output(WebpWriter.DEFAULT, newPath.getAbsolutePath());
        String desc = file.getAbsolutePath()+" -> "+name+"\n"+(file.length()/1024)+"kB->"+(newPath.length()/1024)+"kB,缩小:"+
                (file.length()-newPath.length())*100/file.length()+"%, 耗时:"+(System.currentTimeMillis()- start)+"ms";
        System.out.println(desc);
        int quality = new Magick().getJPEGImageQuality(file);
        System.out.println("原图jpg质量: "+ quality);
        return newPath;
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 测试

尼康相机拍照的压缩-2400万像素

* 尼康相机拍照的压缩:
* E:\photos\编年史\2022\20220305小区内\DSCN1743.JPG -> DSCN1743.webp
* 2695kB->990kB,缩小:63%, 耗时:10954ms
* 原图jpg质量: 86
1
2
3
4

原图和webp按100%显示,对比细节,无明显差异. 右侧图为压缩后的webp

image-20230102203740378

压缩小米11ultra手机拍照的图

E:\photos\imgsync\Xiaomi-M2102K1C-gtgdgrd\0\DCIM\Camera\IMG_20220502_104724.jpg -> IMG_20220502_104724.webp 2170kB->1334kB,缩小:38%, 耗时:7808ms 原图jpg质量: 85

image-20230102204526161

压缩时间远比Android要长,在Android上压缩同等大小的,只要1-3s

# gif转webp

兼容性很差.

Android本身都不支持webp动画,需要第三方库,比如

compile 'com.facebook.fresco:animated-webp:0.12.0'
compile 'com.facebook.fresco:animated-gif:0.12.0'
1
2

https://github.com/humorousz/AnimationSequenceDrawable

压缩率不高,见下方:

D:\Users\Administrator\testgif\14024630.gif -> 14024630.webp 756kB->609kB,缩小:19%, 耗时:6028ms D:\Users\Administrator\testgif\cd112e456ab037dd148f44aab6ab9e9b.gif -> cd112e456ab037dd148f44aab6ab9e9b.webp 2432kB->2037kB,缩小:16%, 耗时:4351ms D:\Users\Administrator\testgif\dave.gif -> dave.webp 8kB->6kB,缩小:22%, 耗时:58ms D:\Users\Administrator\testgif\e5145a1f6ea348e524f3c977d3f32249.gif -> e5145a1f6ea348e524f3c977d3f32249.webp 1496kB->1211kB,缩小:19%, 耗时:1979ms D:\Users\Administrator\testgif\jim.gif -> jim.webp 14kB->12kB,缩小:14%, 耗时:65ms D:\Users\Administrator\testgif\NR6KJFGMS5874.gif -> NR6KJFGMS5874.webp 17kB->12kB,缩小:28%, 耗时:80ms D:\Users\Administrator\testgif\NTPSpqv0yrbpqfep.gif -> NTPSpqv0yrbpqfep.webp 962kB->755kB,缩小:21%, 耗时:1097ms D:\Users\Administrator\testgif\tumblr_mh3ts2XBSM1rbrhnko1_500.gif -> tumblr_mh3ts2XBSM1rbrhnko1_500.webp 657kB->466kB,缩小:29%, 耗时:875ms D:\Users\Administrator\testgif\v2-ec4d371b26dad923867b2752eca734ad_b.gif -> v2-ec4d371b26dad923867b2752eca734ad_b.webp 932kB->819kB,缩小:12%, 耗时:1723ms

综上,gif不应转为webp,而是保持gif格式.

# webp文件元信息的获取

# 判断是否为动图,是否有透明通道

Java后端以MultipartFile形式接受webp图片,并判断是否为动图 (opens new window)

读取动图webp二进制流,前两行会包含一个 ANIM 字符串。否则则为静态,静态图片的二进制流前两行也会包含一个字符串 ALPH

在这里插入图片描述

public Integer uploadPicture(MultipartFile multipartFileImageFile) throws IOException {
		// 定义动图标记,1表示动图
        Integer animated = 0;
        BufferedReader br;
        String line;
        InputStream is = multipartFileImageFile.getInputStream();
        br = new BufferedReader(new InputStreamReader(is));
        // 二进制流有很多行,我们只需要读取前两行就可以判断
        int count = 0;
        while ((line = br.readLine()) != null) {
        	// 为保险起见,我们读取5行,如果其中包含"ANIM"则为动图
            if (line.contains("ANIM")) {
                animated = 1;
            }
            if (count++ >= 5) {
                break;
            }
        }
  		return animated;      
  }
————————————————
版权声明:本文为CSDN博主「lzx专业攻城狮」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44123540/article/details/118796972
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# webp的exif支持

android里已经完美支持webp的exif的读写,那么java里的呢?

# **metadata-extractor (opens new window)**是否支持?

支持webp的metadata的读,但不支持写. 这个库对所有媒体格式都是只支持读,不支持写.

# groupdocs

https://blog.groupdocs.com/metadata/handle-exif-data-of-jpg-png-webp-images-in-java/

# exiftool是否支持?

ExifTool Forum-WebP-Support / webpmux (opens new window)

image-20230102184548184

October 01, 2022, 02:53:56 PM (opens new window)

ExifTool 12.46 is now available with the ability to add/delete/edit EXIF, XMP and ICC_Profile in WebP images.

# java 里对jpg exif的读写的库

https://commons.apache.org/proper/commons-imaging/sampleusage.html

https://github.com/SichengYang/Java-JPEG-Exif-GeoTag-Editor

编辑 (opens new window)
上次更新: 2023/01/04, 12:03:45
颜色模型和色彩空间
google相机拍照携带1s视频的实现和解析

← 颜色模型和色彩空间 google相机拍照携带1s视频的实现和解析→

最近更新
01
截图后的自动压缩工具
12-27
02
图片视频文件根据exif批量重命名
12-27
03
chatgpt图片识别描述功能
02-20
更多文章>
Theme by Vdoing | Copyright © 2020-2025 | 粤ICP备20041795号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式