der*_*ugo 10 c# encoding image unity-game-engine
仅仅是为了测试我通过http下载了一个PNG文件(在这种情况下是通过API从JIRA服务器上下载的)
对于http请求,我有一个非常"标准"的类HttpFileManager我只是添加完整性:
public static class HttpFileManager
{
public void DownloadImage(string url, Action<Texture> successCallback = null, Credentials credentials = null, Action<UnityWebRequest> errorCallback = null)
{
StartCoroutine(DownloadImageProcess(url, successCallback, credentials, errorCallback));
}
private static IEnumerator DownloadImageProcess(string url, Action<Texture> successCallback, Credentials credentials, Action<UnityWebRequest> errorCallback)
{
var www = UnityWebRequestTexture.GetTexture(url);
if (credentials != null)
{
// This simply adds some headers to the request required for JIRA api
// it is not relevant for this question
AddCredentials(www, credentials);
}
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.LogErrorFormat("Download from {0} failed with {1}", url, www.error);
errorCallback?.Invoke(www);
}
else
{
Debug.LogFormat("Download from {0} complete!", url);
successCallback?.Invoke(((DownloadHandlerTexture) www.downloadHandler).texture);
}
}
public static void UploadFile(byte[] rawData, string url, Action<UnityWebRequest> successcallback, Credentials credentials, Action<UnityWebRequest> errorCallback)
private static IEnumerator UploadFileProcess(byte[] rawData, string url, Action<UnityWebRequest> successCallback, Credentials credentials, Action<UnityWebRequest> errorCallback)
{
var form = new WWWForm();
form.AddBinaryData("file",rawData,"Test.png");
var www = UnityWebRequest.Post(url, form);
www.SetRequestHeader("Accept", "application/json");
if (credentials != null)
{
// This simply adds some headers to the request required for JIRA api
// it is not relevant for this question
AddCredentials(www, credentials);
}
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.LogErrorFormat("Upload to {0} failed with code {1} {2}", url, www.responseCode, www.error);
errorCallback?.Invoke(www);
}
else
{
Debug.LogFormat("Upload to {0} complete!", url);
successCallback?.Invoke(www);
}
}
}
Run Code Online (Sandbox Code Playgroud)
后来在我的剧本中我做了
public Texture TestTexture;
// Begin the download
public void DownloadTestImage()
{
_httpFileManager.DownloadImage(ImageGetURL, DownloadImageSuccessCallback, _credentials);
}
// After Download store the Texture
private void DownloadImageSuccessCallback(Texture newTexture)
{
TestTexture = newTexture;
}
// Start the upload
public void UploadTestImage()
{
var data = ((Texture2D) TestTexture).EncodeToPNG();
_httpFileManager.UploadFile(data, ImagePostUrl, UploadSuccessCallback, _credentials);
}
// After Uploading
private static void UploadSuccessCallback(UnityWebRequest www)
{
Debug.Log("Upload worked!");
}
Run Code Online (Sandbox Code Playgroud)
在简历中,问题在于for和back转换
(DownloadHandlerTexture) www.downloadHandler).texture
Run Code Online (Sandbox Code Playgroud)
和
((Texture2D) TestTexture).EncodeToPNG();
Run Code Online (Sandbox Code Playgroud)
结果看起来像这样
在原始图像的顶部; 在底部重新上传的一个.
正如你可以看到它从成长40kb到59kb由系数如此1,475.这同样适用于较大的文件,以便844kb增长到1,02Mb.
所以我的问题是
为什么上传的图像EncodeToPNG()比原始图像更大?
和
是否可以/应该在PNG数据上使用压缩以存档相同的压缩级别(如果压缩是根本问题)?
首先我想可能是不同的颜色深度,但两个图像都是RGBA-32bit
更新
这是两张图片
原始(40kb)(取自此处)
重新上传(59kb)
更新2
我用JPG文件重复测试,EncodeToJPG()结果似乎更糟:
在原始图像的顶部; 在底部重新上传的一个.
这一次它27kb是98kb如此因素2,63.奇怪的是,98kb无论我把quality参数作为参数,文件大小也是不变的EncodeToJPG().
dym*_*oid 10
如果您精确检查两个PNG文件,您会发现差异.它们都具有相同的分辨率,相同的位深度,一些通道数,并且两者都不是隔行扫描的.
但是,原始图像仅包含一个IDAT部分,其保持41370个字节的编码数据的.
源自Unity的图像包含8个IDAT部分:7 x 8192字节和一个2860字节,共60204个字节.
在PNG规范中,有一个注释:
允许多个IDAT块,以便编码器可以在固定数量的内存中工作; 通常,块大小将对应于编码器的缓冲区大小.
此外,IDAT对于相同的源图像,这些部分中包含的数据不一定完全相同.这些IDAT部分保存原始字节数据,首先对其进行预过滤,然后使用压缩进行编码zlib.
因此,PNG编码器可以从5个可用的算法中选择预过滤算法:
Type Name
0 None
1 Sub
2 Up
3 Average
4 Paeth
Run Code Online (Sandbox Code Playgroud)
另外,zlib压缩可以配置为压缩窗口大小,也可以由PNG编码器选择.
检查zlib流产生以下结果:
这解释了二进制数据和数据大小的差异.
您似乎无法控制Unity的PNG编码器,所以很遗憾您不能强迫它选择其他zlib算法.
我想,JPEG文件也是如此 - 编码器只选择生成更大文件的更快算法.
如果您想完全控制Unity中的PNG编码,则需要实现自己的PNG编码器.例如,在Unity论坛上,有一个使用该zlib.net库的PNG编码器样本.您可以通过指定zlib压缩算法来微调编码.
| 归档时间: |
|
| 查看次数: |
549 次 |
| 最近记录: |