素材图片
http://www.taidous.com/data/attachment/block/91/91df09f37bb9b00a2715b65336d82da3.jpg
分辨率 360x300
图片大小 63.6 KB (65,201 字节)
效果图
代码CompressImage.cs
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class CompressImage : MonoBehaviour
{
public RawImage rawImageL;
public RawImage rawImageM;
public RawImage rawImageR;
public Text textL;
public Text textM;
public Text textR;
void Start()
{
string imagePath = "file:///" + Application.dataPath + "/StreamingAssets/SourceImage.jpg";
StartCoroutine(LoadImage(imagePath));
}
IEnumerator LoadImage(string url)
{
Debug.Log(url);
WWW www = new WWW(url);
yield return www;
if (www.isDone)
{
if (www.texture != null)
{
//原始图片
Texture2D imgL = www.texture;
rawImageL.texture = imgL;
textL.text = "运行时占用内存:" + (Profiler.GetRuntimeMemorySize(imgL) / 1024) + "KB\n图片分辨率" + imgL.width + "x" + imgL.height;
//DXT压缩
Texture2D imgM = www.texture;
imgM.Compress(false);
rawImageM.texture = imgM;
textM.text = "运行时占用内存:" + (Profiler.GetRuntimeMemorySize(imgM) / 1024) + "KB\n图片分辨率" + imgM.width + "x" + imgM.height;
//缩放&DXT压缩
Texture2D imgR = www.texture;
//线性缩放
TextureScale.Bilinear(imgR, (int)(imgR.width * 0.4f), (int)(imgR.height * 0.4f));
//开启多线程线性缩放
//TextureScale.ThreadedBilinear(imgR, (int)(imgR.width * 0.4f), (int)(imgR.height * 0.4f));
imgR.Compress(false);
rawImageR.texture = imgR;
textR.text = "运行时占用内存:" + (Profiler.GetRuntimeMemorySize(imgR) / 1024) + "KB\n图片分辨率" + imgR.width + "x" + imgR.height;
}
if (www != null)
{
www = null;
}
}
}
}
代码TextureScale.cs
// 只适用于ARGB32,RGB24和Alpha8格式的Texture并且可读
using System.Threading;
using UnityEngine;
public class TextureScale
{
private 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;
private static int cores;
private static int slice;
//单点插值缩放
public static void Point(Texture2D tex, int newWidth, int newHeight)
{
ThreadedScale(tex, newWidth, newHeight, false, false);
}
//多线程单点插值缩放
public static void ThreadedPoint(Texture2D tex, int newWidth, int newHeight)
{
ThreadedScale(tex, newWidth, newHeight, false, true);
}
//双线性插值缩放
public static void Bilinear(Texture2D tex, int newWidth, int newHeight)
{
ThreadedScale(tex, newWidth, newHeight, true, false);
}
//多线程双线性插值缩放
public static void ThreadedBilinear(Texture2D tex, int newWidth, int newHeight)
{
ThreadedScale(tex, newWidth, newHeight, true, true);
}
private static void ThreadedScale(Texture2D tex, int newWidth, int newHeight, bool useBilinear, bool useThread)
{
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;
if (useThread)
{
cores = Mathf.Min(SystemInfo.processorCount, newHeight);
slice = newHeight / cores;
}
finishCount = 0;
if (mutex == null)
{
mutex = new Mutex(false);
}
if (useThread && 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();
texColors = null;
newColors = null;
}
private static void BilinearScale(System.Object obj)
{
ThreadData threadData = (ThreadData)obj;
for (int y = threadData.start; y < threadData.end; y++)
{
int yFloor = (int)Mathf.Floor(y * ratioY);
int y1 = yFloor * w;
int y2 = (yFloor + 1) * w;
int yw = y * w2;
for (int x = 0; x < w2; x++)
{
int xFloor = (int)Mathf.Floor(x * ratioX);
float 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();
}
private static void PointScale(System.Object obj)
{
ThreadData threadData = (ThreadData)obj;
for (int y = threadData.start; y < threadData.end; y++)
{
int thisY = (int)(ratioY * y) * w;
int yw = y * w2;
for (int 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);
}
}
工程文件下载链接: https://pan.baidu.com/s/1mihVaLM 密码: wn3v