以下為參考 Unity Wiki 網站: http://wiki.unity3d.com/index.php/TextureScale

Unity 官方沒有直接改貼圖大小的API,但是 Wiki 上有,故我們建立以下程式碼 (TextureScale.cs) 並匯入Unity 專案中。 
然後要如何使用呢? 很簡單,如下:

TextureScale.Bilinear (<原先的Texture2D>, <新貼圖的寬>, <新貼圖的高>);

※ 原先的 Texture2D 將會被覆蓋掉

TextureScale.cs



// Only works on ARGB32, RGB24 and Alpha8 textures that are marked readable

using System.Threading;
using UnityEngine;

public class TextureScale
{
public class ThreadData
{
public int start;
public int end;
public ThreadData (int s, int e) {
start = s;
end = e;
}
}

private static Color[] texColors;
private static Color[] newColors;
private static int w;
private static float ratioX;
private static float ratioY;
private static int w2;
private static int finishCount;
private static Mutex mutex;

public static void Point (Texture2D tex, int newWidth, int newHeight)
{
ThreadedScale (tex, newWidth, newHeight, false);
}

public static void Bilinear (Texture2D tex, int newWidth, int newHeight)
{
ThreadedScale (tex, newWidth, newHeight, true);
}

private static void ThreadedScale (Texture2D tex, int newWidth, int newHeight, bool useBilinear)
{
texColors = tex.GetPixels();
newColors = new Color[newWidth * newHeight];
if (useBilinear)
{
ratioX = 1.0f / ((float)newWidth / (tex.width-1));
ratioY = 1.0f / ((float)newHeight / (tex.height-1));
}
else {
ratioX = ((float)tex.width) / newWidth;
ratioY = ((float)tex.height) / newHeight;
}
w = tex.width;
w2 = newWidth;
var cores = Mathf.Min(SystemInfo.processorCount, newHeight);
var slice = newHeight/cores;

finishCount = 0;
if (mutex == null) {
mutex = new Mutex(false);
}
if (cores > 1)
{
int i = 0;
ThreadData threadData;
for (i = 0; i < cores-1; i++) {
threadData = new ThreadData(slice * i, slice * (i + 1));
ParameterizedThreadStart ts = useBilinear ? new ParameterizedThreadStart(BilinearScale) : new ParameterizedThreadStart(PointScale);
Thread thread = new Thread(ts);
thread.Start(threadData);
}
threadData = new ThreadData(slice*i, newHeight);
if (useBilinear)
{
BilinearScale(threadData);
}
else
{
PointScale(threadData);
}
while (finishCount < cores)
{
Thread.Sleep(1);
}
}
else
{
ThreadData threadData = new ThreadData(0, newHeight);
if (useBilinear)
{
BilinearScale(threadData);
}
else
{
PointScale(threadData);
}
}

tex.Resize(newWidth, newHeight);
tex.SetPixels(newColors);
tex.Apply();
}

public static void BilinearScale (System.Object obj)
{
ThreadData threadData = (ThreadData) obj;
for (var y = threadData.start; y < threadData.end; y++)
{
int yFloor = (int)Mathf.Floor(y * ratioY);
var y1 = yFloor * w;
var y2 = (yFloor+1) * w;
var yw = y * w2;

for (var x = 0; x < w2; x++) {
int xFloor = (int)Mathf.Floor(x * ratioX);
var xLerp = x * ratioX-xFloor;
newColors[yw + x] = ColorLerpUnclamped(ColorLerpUnclamped(texColors[y1 + xFloor], texColors[y1 + xFloor+1], xLerp),
ColorLerpUnclamped(texColors[y2 + xFloor], texColors[y2 + xFloor+1], xLerp),
y*ratioY-yFloor);
}
}

mutex.WaitOne();
finishCount++;
mutex.ReleaseMutex();
}

public static void PointScale (System.Object obj)
{
ThreadData threadData = (ThreadData) obj;
for (var y = threadData.start; y < threadData.end; y++)
{
var thisY = (int)(ratioY * y) * w;
var yw = y * w2;
for (var x = 0; x < w2; x++) {
newColors[yw + x] = texColors[(int)(thisY + ratioX*x)];
}
}

mutex.WaitOne();
finishCount++;
mutex.ReleaseMutex();
}

private static Color ColorLerpUnclamped (Color c1, Color c2, float value)
{
return new Color (c1.r + (c2.r - c1.r)*value,
c1.g + (c2.g - c1.g)*value,
c1.b + (c2.b - c1.b)*value,
c1.a + (c2.a - c1.a)*value);
}
}

    全站熱搜

    黃彥霖 發表在 痞客邦 留言(0) 人氣()