HMCL icon indicating copy to clipboard operation
HMCL copied to clipboard

WEBP Support

Open burningtnt opened this issue 2 years ago • 13 comments

使用了自己写的 SimpleWEBP 来解码 WEBP 图像,仅支持 VP8L 无损压缩,可以使 HMCL 本体大小减少 56KB。SimpleWEBP 使用 BCIG 来做到零反射兼容不同 JavaFX 版本,经测试,对启动时间影响极小,为毫秒级。

Close #2015

问题:

  • background.jpg 和 background-classic.jpg 是 JPEG 压缩的图片,无损 WEBP 压缩无法减小其大小(反而会增大)
  • SimpleWEBP 目前使用 BCIG 来零反射兼容两种不同的 JavaFX 版本,是否有更多 JavaFX 版本需要兼容?

burningtnt avatar Jun 10 '23 06:06 burningtnt

重构了一下 SimpleWebp,从 30KB 压缩到了 23.7KB,请 Glavo 批一下 workflow

burningtnt avatar Jun 16 '23 09:06 burningtnt

我来解决一下冲突

burningtnt avatar Jun 23 '23 11:06 burningtnt

@huanghongxun 已解决冲突

burningtnt avatar Jun 25 '23 10:06 burningtnt

java.awt.Image 有类似于 JavaFx 的 ImageLoader 注册表吗?目前对于 java.awt.Image 的 WEBP 加载是靠 PNGJavaFXUtils.writeImageToArray(new javafx.scene.image.Image(...))) 实现的

没事了,AWT 的 ImageLoader 是硬编码的,见 sun.awt.image.InputStreamImageSource#getDecoder(java.io.InputStream)

protected ImageDecoder getDecoder(InputStream is) {
    if (!is.markSupported())
        is = new BufferedInputStream(is);
    try {
      /* changed to support png
         is.mark(6);
         */
      is.mark(8);
        int c1 = is.read();
        int c2 = is.read();
        int c3 = is.read();
        int c4 = is.read();
        int c5 = is.read();
        int c6 = is.read();
        // added to support png
        int c7 = is.read();
        int c8 = is.read();
        // end of adding
        is.reset();
        is.mark(-1);
        if (c1 == 'G' && c2 == 'I' && c3 == 'F' && c4 == '8') {
            return new GifImageDecoder(this, is);
        } else if (c1 == '\377' && c2 == '\330' && c3 == '\377') {
            return new JPEGImageDecoder(this, is);
        } else if (c1 == '#' && c2 == 'd' && c3 == 'e' && c4 == 'f') {
            return new XbmImageDecoder(this, is);
        // } else if (c1 == '!' && c2 == ' ' && c3 == 'X' && c4 == 'P' &&
        //            c5 == 'M' && c6 == '2') {
        //     return new Xpm2ImageDecoder(this, is);
            // added to support png
        } else if (c1 == 137 && c2 == 80 && c3 == 78 &&
            c4 == 71 && c5 == 13 && c6 == 10 &&
            c7 == 26 && c8 == 10) {
            return new PNGImageDecoder(this, is);
        }
        // end of adding
    } catch (IOException e) {
    }
    return null;
}

burningtnt avatar Jul 07 '23 09:07 burningtnt

我在 AwtUtils 里加个方法来解析吧

burningtnt avatar Jul 07 '23 09:07 burningtnt

现在无论是 JavaFx 还是 Swing 的 Image 都可以正常的从 webp 中解码了

burningtnt avatar Jul 08 '23 12:07 burningtnt

警告:该 PR 可能与 #2370 冲突 (已解决)

burningtnt avatar Jul 10 '23 04:07 burningtnt

已解决冲突,可以正常合并

burningtnt avatar Jul 12 '23 01:07 burningtnt

3.5.4.234:

截屏2023-11-10 22 55 54

3.5.unofficial-5fac9ca:

截屏2023-11-10 23 51 46

dock 栏直接变白,HMCL 左上角图标变大

zkitefly avatar Nov 10 '23 23:11 zkitefly

Dock 栏 Icon 渲染异常问题:已修复 窗口左上角 Icon 渲染异常问题:已修复

burningtnt avatar Nov 11 '23 03:11 burningtnt

已大幅度简化 SimpleWEBP,最终可以使 HMCL 大小减小 47KB

burningtnt avatar Dec 29 '23 13:12 burningtnt

收益不大。 目前 HMCL 本体下载走的第三方 CDN,体积大一点也不会再增加黄鱼服务器负担,所以减小几十 k 的意义很小。

其实,对于 HMCL 而言,56KB 确实很小。这里我更希望考虑到的是宣传效益。当时 Enhance Mod Download PR 大改模组下载 UI 的时候、率先支持 NeoForge、Quilt 等的时候,配合上宣发,确确实实是吸引了不少用户。我希望借迁移到 webp 的机会,配合 NeoForge 支持,再能够宣传一波。

新增一个库依赖意味隐含 BUG 的可能性增加,尤其是这个库需要打破 JavaFX 模块封装,这导致需要更多精力测试 JavaFX 兼容性,而且也需要你花费精力去维护此库,提高了维护成本。

维护成本确实上升了。几个月前,我已经通过各种渠道宣发 PR Collection 版本,为各 PR 收集反馈。经过测试,目前 SimpleWEBP 与各 JavaFX 版本兼容性良好。未来 HMCL 能够快速更新的话,并配合上目前已经建立的用户大群和小众硬件交流群,我相信即使兼容性出现问题,也只会出现在部分小众硬件上,能够快速的得到反馈并修复。

此外,由于目前 HMCL 的所有内置图片均通过 FXUtils.newBuiltinImage 加载,此处理论上可以不打破 JavaFX 封装,直接调用 SimpleWEBP 的加载函数并复制到 JavaFX 的 Image 中。

目前 webp 生态不够成熟,使用 webp 会破坏一些工作流,比如由于 GitHub 网页端不支持 webp,合并本 PR 意味未来我们无法在网页端审查图标变化,比如一些开发者可能因为处理 webp 比 png 更繁琐而被拦在门外。

这一点确实如此。目前很多工具都无法处理 webp 图像,转码器几乎就只有 cwebp / dwebp Google 原生的工具。好消息是 IdeaIC/U 都支持了 webp 图像预览。https://github.com/orgs/community/discussions/5470 GitHub 两年前就有人希望支持,但一直没能实现……

综合考量,我认为利大于弊。考虑到维护成本和开发成本,我认为可以允许 PNG 与 WEBP 图像在开发中并行(即 PR 审查阶段可以直接使用 PNG 开发,确认没问题了再迁移到 webp 再做测试)

burningtnt avatar Mar 11 '24 11:03 burningtnt

其实,对于 HMCL 而言,56KB 确实很小。这里我更希望考虑到的是宣传效益。当时 Enhance Mod Download PR 大改模组下载 UI 的时候、率先支持 NeoForge、Quilt 等的时候,配合上宣发,确确实实是吸引了不少用户。我希望借迁移到 webp 的机会,配合 NeoForge 支持,再能够宣传一波。

使用 webp 图标没有增加任何实际功能,唯一能宣传的点是体积小,但 HMCL 并不是以体积小为宣传点,相比其他主流启动器在这方面也没什么优势。除非支持了有损 webp 来允许使用 webp 作为背景,否则使用 webp 存储图标并没有可宣传的地方,但有损 webp 支持过于复杂,维护成本很高,真的要实现那建议直接提交给 OpenJFX 主线,未来可以由 OpenJFX 团队进行测试和维护,HMCL 再通过运行时测试 OpenJFX 是否支持 webp 来启用 webp 背景加载。

此外,由于目前 HMCL 的所有内置图片均通过 FXUtils.newBuiltinImage 加载,此处理论上可以不打破 JavaFX 封装,直接调用 SimpleWEBP 的加载函数并复制到 JavaFX 的 Image 中。

那样高分辨率支持等功能都要在 HMCL 内手动实现,更复杂了。

综合考量,我认为利大于弊。考虑到维护成本和开发成本,我认为可以允许 PNG 与 WEBP 图像在开发中并行(即 PR 审查阶段可以直接使用 PNG 开发,确认没问题了再迁移到 webp 再做测试)

这样同样很麻烦,原本仅在网页端可完成工作都需要电脑上进行了。

总之我还是没看出这项工作的实际收益,但造成的困扰是显而易见的。如果没有特别大的收益,我依然不愿意接受本 PR。

Glavo avatar Mar 11 '24 12:03 Glavo