• Unity中使用WebP类型文件


    简介

    WebP是一种由Google开发的图像格式,旨在提供更高的压缩效率和更好的图像质量,特别是针对Web上的图像传输。以下是一些关键特点:

    压缩效率: WebP通常能够提供比JPEG更好的压缩效率,尤其是对于包含大量颜色的图像。

    透明度支持: WebP支持有损和无损压缩,而且能够在有损压缩中保留透明度。这是与JPEG相比的一个优势,因为JPEG不支持透明度。

    动态图像: WebP格式还支持动态图像,类似于GIF。这使得它适用于展示简单的动画。

    颜色配置: WebP支持多种颜色配置,包括灰度、彩色和透明。

    支持有损和无损: WebP可以使用有损和无损两种压缩模式。无损模式保留图像质量,而有损模式提供更高的压缩率但可能会有一些细微的视觉损失。

    快速解码: WebP图像可以在相对较短的时间内进行解码,这对于Web页面上的快速加载非常重要。

    WebP已经得到了许多现代Web浏览器的支持,包括Google Chrome、Mozilla Firefox、Microsoft Edge等。然而,由于不是所有的图像编辑软件都支持WebP,有时可能需要转换工具来处理这种格式的图像。

    Unity中使用WebP文件

    Unity默认并不支持WebP格式,因此需要我们拿到数据后对其进行转换。

    github有一些开源的方案,诸如:

    你也可以从谷歌开源的libwebp库中下载源码,并编译为对应平台的插件。

    笔者的需求是:windows环境下获得各个直播平台的玩家头像(tk平台是webp格式),并展示在UI上。因此需要判断头像是否是webp格式,然后再转换为unity支持的texture。

    WebP格式验证

    WebP格式文件前12个字节是固定的标识字节序列。前4个字节是 “RIFF”,5-8字节标识文件大小(以 little-endian 表示),最后4个字节标识文件类型,WebP图片是 “WEBP”。
    RIFF 是 Resource Interchange File Format 的缩写,是一种通用的文件格式标识符。

    Microsoft在AVI和WAV这两种著名的文件格式中,都使用RIFF的格式当成它们的基础。

    RIFF文件由一个简单的表头(header)跟随着多个"chunks"所组。其格式完全跟IFF一样,除整数的存储方式不一样以外。

    • 表头(Header)
      • 4位组(bytes):固定为"RIFF".
      • 4位组:little-endian 32-bit正整数,整个文件的大小,扣掉识别字符和长度,共8个字节。
      • 4位组:这个文件的类型字符,例如:"AVI “或"WAVE”.
    • 接下来是区块(Chunks),每个区块包含:
      • 4位组:此区块的ASCII识别字,例如:"fmt “或"data”.
      • 4位组:little-endian 32-bit正整数,表示本区块的长度(这个正整数本身和区块识别字的长度不算在内)。
      • 不固定长度字段:此区块的资料,大小等同前一栏之正整数。
      • 假如区块的长度不为偶数,则填入一个byte。

    针对我们的项目,我这里只验证了RIFF和WEBP标识,代码如下:

        public static bool IsWebP(byte[] imageData)
        {
            if (imageData.Length<12)
            {
                return false;
            }
            // WebP文件头的标识字节序列
            byte[] webpHeader = { 0x52, 0x49, 0x46, 0x46 };//R对应的ASCII码用16进制表示为 0x52 ,当然也可以使用十进制 82,或者二进制 0b1010010 (使用二进制需要使用0b前缀来标识)
    
            // 检查前4个字节是否匹配WebP头部
            for (int i = 0; i < webpHeader.Length; i++)
            {
                if (imageData.Length <= i || imageData[i] != webpHeader[i])
                {
                    return false;
                }
            }
    
            // 提取文件大小(little-endian)
            int fileSize = BitConverter.ToInt32(imageData, 4);//fileSize+8==imageData.Length
    
            // 文件类型标识符 "WEBP"
            byte[] webpIdentifier = { 0x57, 0x45, 0x42, 0x50 };
    
            // 检查文件类型标识符
            for (int i = 8; i < 12; i++)
            {
                if (imageData.Length <= i || imageData[i] != webpIdentifier[i - 8])
                {
                    return false;
                }
            }        
            return true;
        }
    
    • 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

    转换为texture

    笔者使用了上述提到的webp-unity3d 。在编辑器下顺利读取转化webp图片。需要注意的是,该作者通过CreateTexture2DFromWebP获得到的Texture2D是不可读的。可以在该方法中增加参数,Apply生成ITexture2D时通过参数来供外部自由设置。

    其它

    官方技术文档

    后记

    上述webp-unity3d 在打包后会报错:

    DllNotFoundException: Unable to load DLL 'webp'. Tried the load the following dynamic libraries: Unable to load dynamic library 'webp' because of 'Failed to open the requested dynamic library (0x06000000) - 找不到指定的模块。  (WinError:0000007e)
      at WebP.Extern.NativeBindings.WebPGetInfo (System.IntPtr data, System.UIntPtr data_size, System.Int32& width, System.Int32& height) [0x00000] in <00000000000000000000000000000000>:0 
      at WebP.Texture2DExt.CreateTexture2DFromWebP (System.Byte[] lData, System.Boolean lMipmaps, System.Boolean lLinear, System.Boolean resultTextureReadable, WebP.Status& lError, WebP.Texture2DExt+ScalingFunction scalingFunction) [0x00000] in <00000000000000000000000000000000>:0 
      at UnityWebRequestMgr+<_GetTexture>d__10.MoveNext () [0x00000] in <00000000000000000000000000000000>:0 
      at UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) [0x00000] in <00000000000000000000000000000000>:0
    
    • 1
    • 2
    • 3
    • 4
    • 5

    切换成unity.webp ,PC环境下实现了需求(其它平台未测)。

  • 相关阅读:
    hcie网上培训的优势什么?
    面向对象设计模式之工厂方法模式
    激光雷达的厮杀18年:西方“诸神黄昏”,东方“新王隐现”
    DNA-CuInSeQDs近红外CuInSe量子点包裹脱氧核糖核酸DNA
    如何找回删除的文件?数据恢复,看这几个方法
    java 下载文件名 编码
    怎么算集装箱能装多少货物
    从React源码来学hooks是不是更香呢
    Java 最常见的 200+ 面试题:面试必备
    工业镜头中的远心镜头与普通镜头的光路
  • 原文地址:https://blog.csdn.net/iningwei/article/details/134061118