Texture resize done using raw data from texture2d. Got rid of unused plugins. Improved image change timing

This commit is contained in:
ftc
2021-01-17 12:12:36 +03:00
parent 7eb7ac33cc
commit fbc829ba33
12 changed files with 96 additions and 192 deletions
-12
View File
@@ -302,18 +302,6 @@
<Reference Include="Unity.Analytics.Tracker"> <Reference Include="Unity.Analytics.Tracker">
<HintPath>C:/Work/UPhotoFrame/Library/PackageCache/com.unity.analytics@3.2.2/Unity.Analytics.Tracker.dll</HintPath> <HintPath>C:/Work/UPhotoFrame/Library/PackageCache/com.unity.analytics@3.2.2/Unity.Analytics.Tracker.dll</HintPath>
</Reference> </Reference>
<Reference Include="SixLabors.ImageSharp">
<HintPath>C:/Work/UPhotoFrame/Assets/Plugins/SixLabors.ImageSharp.dll</HintPath>
</Reference>
<Reference Include="System.Memory">
<HintPath>C:/Work/UPhotoFrame/Assets/Plugins/System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe">
<HintPath>C:/Work/UPhotoFrame/Assets/Plugins/System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Buffers">
<HintPath>C:/Work/UPhotoFrame/Assets/Plugins/System.Buffers.dll</HintPath>
</Reference>
<Reference Include="mscorlib"> <Reference Include="mscorlib">
<HintPath>D:/Program Files/Unity2018.4.6f1/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/mscorlib.dll</HintPath> <HintPath>D:/Program Files/Unity2018.4.6f1/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/mscorlib.dll</HintPath>
</Reference> </Reference>
Binary file not shown.
@@ -1,33 +0,0 @@
fileFormatVersion: 2
guid: 57be6a18d4b2a2c469cb368678ff380a
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.
-33
View File
@@ -1,33 +0,0 @@
fileFormatVersion: 2
guid: 4998389d070a0614fa7bbef6d8966f86
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.
-33
View File
@@ -1,33 +0,0 @@
fileFormatVersion: 2
guid: 3d2ebe00670c0154b8f627bc62b7bf5d
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
@@ -1,33 +0,0 @@
fileFormatVersion: 2
guid: 4eec2a1318993b04ea65c96e76ce0bef
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
+23 -35
View File
@@ -1,15 +1,13 @@
using System.Collections; using System.Collections;
using System.IO;
using UnityEngine; using UnityEngine;
using UnityEngine.Networking; using UnityEngine.Networking;
using UnityEngine.UI; using UnityEngine.UI;
using Image = UnityEngine.UI.Image;
using Color = UnityEngine.Color;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp;
public class PhotoFrame : MonoBehaviour public class PhotoFrame : MonoBehaviour
{ {
const float PHOTO_INTERVAL = 5f;
const float ANIMATION_LENGTH = 2f;
[SerializeField] [SerializeField]
GameObject mainUI; GameObject mainUI;
@@ -35,6 +33,7 @@ public class PhotoFrame : MonoBehaviour
public void Start() public void Start()
{ {
Screen.sleepTimeout = SleepTimeout.NeverSleep;
currentImage = 0; currentImage = 0;
ActivateUI(true); ActivateUI(true);
} }
@@ -86,13 +85,12 @@ public class PhotoFrame : MonoBehaviour
NextImage.color = transparent; NextImage.color = transparent;
while (true) while (true)
{ {
var startTime = Time.realtimeSinceStartup;
int imageIndex = Random.Range(0, loader.images.Count); int imageIndex = Random.Range(0, loader.images.Count);
string imageUrl = loader.images[imageIndex]; string imageUrl = loader.images[imageIndex];
var path = Application.persistentDataPath + "/source." + System.IO.Path.GetExtension(imageUrl);
var request = UnityWebRequest.Get(imageUrl); var request = UnityWebRequest.Get(imageUrl);
request.downloadHandler = new DownloadHandlerFile(path); request.downloadHandler = new DownloadHandlerTexture(true);
yield return request.SendWebRequest(); yield return request.SendWebRequest();
if (request.isNetworkError || request.isHttpError) if (request.isNetworkError || request.isHttpError)
@@ -101,19 +99,28 @@ public class PhotoFrame : MonoBehaviour
continue; continue;
} }
SetImageTexture(NextImage, path); var downloadTime = Time.realtimeSinceStartup - startTime;
request.downloadHandler.Dispose(); if (PHOTO_INTERVAL > downloadTime)
{
yield return new WaitForSeconds(PHOTO_INTERVAL - downloadTime);
}
var dh = request.downloadHandler as DownloadHandlerTexture;
var tex = dh.texture;
SetImageTexture(NextImage, tex);
dh.Dispose();
request.Dispose(); request.Dispose();
float currentStart = CurrentImage.color.a; float currentStart = CurrentImage.color.a;
float currentFinish = transparent.a; float currentFinish = transparent.a;
float nextStart = NextImage.color.a; float nextStart = NextImage.color.a;
float nextFinish = opaque.a; float nextFinish = opaque.a;
float startTime = Time.time; startTime = Time.time;
while (Time.time < startTime + 2f) while (Time.time < startTime + ANIMATION_LENGTH)
{ {
float ct = Time.time; float ct = Time.time;
float x = (ct - startTime) / 2f; float x = (ct - startTime) / ANIMATION_LENGTH;
float currentA = currentStart + x * (currentFinish - currentStart); float currentA = currentStart + x * (currentFinish - currentStart);
Color cC = new Color(CurrentImage.color.r, CurrentImage.color.g, CurrentImage.color.b, currentA); Color cC = new Color(CurrentImage.color.r, CurrentImage.color.g, CurrentImage.color.b, currentA);
CurrentImage.color = cC; CurrentImage.color = cC;
@@ -122,7 +129,6 @@ public class PhotoFrame : MonoBehaviour
NextImage.color = nC; NextImage.color = nC;
yield return null; yield return null;
} }
yield return new WaitForSeconds(5f);
currentImage = (currentImage + 1) % images.Length; currentImage = (currentImage + 1) % images.Length;
Resources.UnloadUnusedAssets(); Resources.UnloadUnusedAssets();
@@ -130,7 +136,7 @@ public class PhotoFrame : MonoBehaviour
} }
} }
private void SetImageTexture(Image nextImage, string path) private void SetImageTexture(Image nextImage, Texture2D tex)
{ {
if (nextImage.sprite != null) if (nextImage.sprite != null)
{ {
@@ -155,31 +161,13 @@ public class PhotoFrame : MonoBehaviour
maxWidth = 2048; maxWidth = 2048;
maxHeight = (int)(2048 / imageWidth * imageHeight); maxHeight = (int)(2048 / imageWidth * imageHeight);
} }
Texture2D tex = new Texture2D(2, 2);
tex.LoadImage(File.ReadAllBytes(path));
float factor = Mathf.Min((float) maxWidth / tex.width, (float)maxHeight / tex.height); float factor = Mathf.Min((float) maxWidth / tex.width, (float)maxHeight / tex.height);
int newWidth = (int)(tex.width * factor); int newWidth = (int)(tex.width * factor);
int newHeight = (int)(tex.height * factor); int newHeight = (int)(tex.height * factor);
Destroy(tex); TextureScale.Bilinear(tex, newWidth, newHeight);
var newPath = Scale(path, newWidth, newHeight);
tex = new Texture2D(2, 2);
tex.LoadImage(File.ReadAllBytes(newPath));
//TextureScale.Bilinear(tex, newWidth, newHeight);
//TextureScale.Point(tex, newWidth, newHeight);
//Color[] cs = tex.GetPixels();
var sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), Vector2.zero); var sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), Vector2.zero);
nextImage.sprite = sprite; nextImage.sprite = sprite;
nextImage.rectTransform.anchorMin = new Vector2((maxWidth - (float)newWidth) / maxWidth / 2, (maxHeight - (float)newHeight) / maxHeight / 2); nextImage.rectTransform.anchorMin = new Vector2((maxWidth - (float)newWidth) / maxWidth / 2, (maxHeight - (float)newHeight) / maxHeight / 2);
} }
private string Scale(string path, int newWidth, int newHeight)
{
var resultPath = Path.GetDirectoryName(path) + "/target." + Path.GetExtension(path);
using (SixLabors.ImageSharp.Image image = SixLabors.ImageSharp.Image.Load(path))
{
image.Mutate(x => x.Resize(newWidth, newHeight));
image.Save(resultPath);
}
return resultPath;
}
} }
+71 -11
View File
@@ -1,4 +1,10 @@
using System.Threading; // Initial version at: http://wiki.unity3d.com/index.php/TextureScale#TextureScale.cs
// Modified by ftc to work with raw texture data (it consumes less memory).
// Currently works only on RGB24 and RGBA32 textures.
using System;
using System.Threading;
using Unity.Collections;
using UnityEngine; using UnityEngine;
public class TextureScale public class TextureScale
@@ -14,8 +20,10 @@ public class TextureScale
} }
} }
private static Color32[] texColors; private static NativeArray<byte> texBytes;
private static TextureFormat texFormat;
private static Color32[] newColors; private static Color32[] newColors;
private static int h;
private static int w; private static int w;
private static float ratioX; private static float ratioX;
private static float ratioY; private static float ratioY;
@@ -35,8 +43,16 @@ public class TextureScale
private static void ThreadedScale(Texture2D tex, int newWidth, int newHeight, bool useBilinear) private static void ThreadedScale(Texture2D tex, int newWidth, int newHeight, bool useBilinear)
{ {
texColors = tex.GetPixels32(); texBytes = tex.GetRawTextureData<byte>();
texFormat = tex.format;
if (texFormat != TextureFormat.RGB24 && texFormat != TextureFormat.RGBA32)
{
throw new NotImplementedException();
}
if (newColors == null || newColors.Length < newWidth * newHeight)
{
newColors = new Color32[newWidth * newHeight]; newColors = new Color32[newWidth * newHeight];
}
if (useBilinear) if (useBilinear)
{ {
ratioX = 1.0f / ((float)newWidth / (tex.width - 1)); ratioX = 1.0f / ((float)newWidth / (tex.width - 1));
@@ -48,6 +64,7 @@ public class TextureScale
ratioY = ((float)tex.height) / newHeight; ratioY = ((float)tex.height) / newHeight;
} }
w = tex.width; w = tex.width;
h = tex.height;
w2 = newWidth; w2 = newWidth;
var cores = Mathf.Min(SystemInfo.processorCount, newHeight); var cores = Mathf.Min(SystemInfo.processorCount, newHeight);
var slice = newHeight / cores; var slice = newHeight / cores;
@@ -96,11 +113,54 @@ public class TextureScale
} }
tex.Resize(newWidth, newHeight); tex.Resize(newWidth, newHeight);
tex.SetPixels32(newColors); var newBytes = tex.GetRawTextureData<byte>();
for (int i = 0; i < newWidth * newHeight; i++)
{
var color = newColors[i];
if (tex.format == TextureFormat.RGB24)
{
int s = 3 * i;
newBytes[s] = color.r;
newBytes[s + 1] = color.g;
newBytes[s + 2] = color.b;
}
else if (tex.format == TextureFormat.RGBA32)
{
int s = 4 * i;
newBytes[s] = color.r;
newBytes[s + 1] = color.g;
newBytes[s + 2] = color.b;
newBytes[s + 3] = color.a;
}
}
tex.Apply(); tex.Apply();
texColors = null; //newColors = null;
newColors = null; }
private static Color32 GetColor(int position)
{
if (texFormat == TextureFormat.RGB24)
{
int s = (int)position * 3;
Color32 result = new Color32();
result.r = texBytes[s];
result.g = texBytes[s + 1];
result.b = texBytes[s + 2];
result.a = 0;
return result;
}
else if (texFormat == TextureFormat.RGBA32)
{
int s = (int)position * 4;
Color32 result = new Color32();
result.r = texBytes[s];
result.g = texBytes[s + 1];
result.b = texBytes[s + 2];
result.a = texBytes[s + 3];
return result;
}
else throw new NotImplementedException();
} }
public static void BilinearScale(System.Object obj) public static void BilinearScale(System.Object obj)
@@ -109,6 +169,7 @@ public class TextureScale
for (var y = threadData.start; y < threadData.end; y++) for (var y = threadData.start; y < threadData.end; y++)
{ {
int yFloor = (int)Mathf.Floor(y * ratioY); int yFloor = (int)Mathf.Floor(y * ratioY);
while (yFloor + 1 >= h) yFloor--;
var y1 = yFloor * w; var y1 = yFloor * w;
var y2 = (yFloor + 1) * w; var y2 = (yFloor + 1) * w;
var yw = y * w2; var yw = y * w2;
@@ -117,12 +178,11 @@ public class TextureScale
{ {
int xFloor = (int)Mathf.Floor(x * ratioX); int xFloor = (int)Mathf.Floor(x * ratioX);
var xLerp = x * ratioX - xFloor; var xLerp = x * ratioX - xFloor;
newColors[yw + x] = ColorLerpUnclamped(ColorLerpUnclamped(texColors[y1 + xFloor], texColors[y1 + xFloor + 1], xLerp), var c1 = ColorLerpUnclamped(GetColor(y1 + xFloor), GetColor(y1 + xFloor + 1), xLerp);
ColorLerpUnclamped(texColors[y2 + xFloor], texColors[y2 + xFloor + 1], xLerp), var c2 = ColorLerpUnclamped(GetColor(y2 + xFloor), GetColor(y2 + xFloor + 1), xLerp);
y * ratioY - yFloor); newColors[yw + x] = ColorLerpUnclamped(c1, c2, y * ratioY - yFloor);
} }
} }
mutex.WaitOne(); mutex.WaitOne();
finishCount++; finishCount++;
mutex.ReleaseMutex(); mutex.ReleaseMutex();
@@ -137,7 +197,7 @@ public class TextureScale
var yw = y * w2; var yw = y * w2;
for (var x = 0; x < w2; x++) for (var x = 0; x < w2; x++)
{ {
newColors[yw + x] = texColors[(int)(thisY + ratioX * x)]; newColors[yw + x] = GetColor((int)(thisY + ratioX * x));
} }
} }
+1 -1
View File
@@ -592,7 +592,7 @@ PlayerSettings:
scriptingDefineSymbols: {} scriptingDefineSymbols: {}
platformArchitecture: {} platformArchitecture: {}
scriptingBackend: scriptingBackend:
Android: 1 Android: 0
il2cppCompilerConfiguration: il2cppCompilerConfiguration:
Android: 2 Android: 2
managedStrippingLevel: {} managedStrippingLevel: {}