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格式,因此需要我们拿到数据后对其进行转换。
github有一些开源的方案,诸如:
你也可以从谷歌开源的libwebp库中下载源码,并编译为对应平台的插件。
笔者的需求是:windows环境下获得各个直播平台的玩家头像(tk平台是webp格式),并展示在UI上。因此需要判断头像是否是webp格式,然后再转换为unity支持的texture。
WebP格式文件前12个字节是固定的标识字节序列。前4个字节是 “RIFF”,5-8字节标识文件大小(以 little-endian 表示),最后4个字节标识文件类型,WebP图片是 “WEBP”。
RIFF 是 Resource Interchange File Format 的缩写,是一种通用的文件格式标识符。
Microsoft在AVI和WAV这两种著名的文件格式中,都使用RIFF的格式当成它们的基础。
RIFF文件由一个简单的表头(header)跟随着多个"chunks"所组。其格式完全跟IFF一样,除整数的存储方式不一样以外。
针对我们的项目,我这里只验证了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;
}
笔者使用了上述提到的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
切换成unity.webp ,PC环境下实现了需求(其它平台未测)。