TextureScale.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. using System;
  2. using System.Threading;
  3. using UnityEngine;
  4. public class TextureScale
  5. {
  6. public static void Point(Texture2D tex, int newWidth, int newHeight)
  7. {
  8. TextureScale.ThreadedScale(tex, newWidth, newHeight, false);
  9. }
  10. public static void Bilinear(Texture2D tex, int newWidth, int newHeight)
  11. {
  12. TextureScale.ThreadedScale(tex, newWidth, newHeight, true);
  13. }
  14. private static void ThreadedScale(Texture2D tex, int newWidth, int newHeight, bool useBilinear)
  15. {
  16. TextureScale.texColors = tex.GetPixels();
  17. TextureScale.newColors = new Color[newWidth * newHeight];
  18. if (useBilinear)
  19. {
  20. TextureScale.ratioX = 1f / ((float)newWidth / (float)(tex.width - 1));
  21. TextureScale.ratioY = 1f / ((float)newHeight / (float)(tex.height - 1));
  22. }
  23. else
  24. {
  25. TextureScale.ratioX = (float)tex.width / (float)newWidth;
  26. TextureScale.ratioY = (float)tex.height / (float)newHeight;
  27. }
  28. TextureScale.w = tex.width;
  29. TextureScale.w2 = newWidth;
  30. int num = Mathf.Min(SystemInfo.processorCount, newHeight);
  31. int num2 = newHeight / num;
  32. TextureScale.finishCount = 0;
  33. if (TextureScale.mutex == null)
  34. {
  35. TextureScale.mutex = new Mutex(false);
  36. }
  37. if (num > 1)
  38. {
  39. int i;
  40. TextureScale.ThreadData threadData;
  41. for (i = 0; i < num - 1; i++)
  42. {
  43. threadData = new TextureScale.ThreadData(num2 * i, num2 * (i + 1));
  44. ParameterizedThreadStart start = (!useBilinear) ? new ParameterizedThreadStart(TextureScale.PointScale) : new ParameterizedThreadStart(TextureScale.BilinearScale);
  45. Thread thread = new Thread(start);
  46. thread.Start(threadData);
  47. }
  48. threadData = new TextureScale.ThreadData(num2 * i, newHeight);
  49. if (useBilinear)
  50. {
  51. TextureScale.BilinearScale(threadData);
  52. }
  53. else
  54. {
  55. TextureScale.PointScale(threadData);
  56. }
  57. while (TextureScale.finishCount < num)
  58. {
  59. Thread.Sleep(1);
  60. }
  61. }
  62. else
  63. {
  64. TextureScale.ThreadData obj = new TextureScale.ThreadData(0, newHeight);
  65. if (useBilinear)
  66. {
  67. TextureScale.BilinearScale(obj);
  68. }
  69. else
  70. {
  71. TextureScale.PointScale(obj);
  72. }
  73. }
  74. tex.Resize(newWidth, newHeight);
  75. tex.SetPixels(TextureScale.newColors);
  76. tex.Apply();
  77. }
  78. public static void BilinearScale(object obj)
  79. {
  80. TextureScale.ThreadData threadData = (TextureScale.ThreadData)obj;
  81. for (int i = threadData.start; i < threadData.end; i++)
  82. {
  83. int num = (int)Mathf.Floor((float)i * TextureScale.ratioY);
  84. int num2 = num * TextureScale.w;
  85. int num3 = (num + 1) * TextureScale.w;
  86. int num4 = i * TextureScale.w2;
  87. for (int j = 0; j < TextureScale.w2; j++)
  88. {
  89. int num5 = (int)Mathf.Floor((float)j * TextureScale.ratioX);
  90. float value = (float)j * TextureScale.ratioX - (float)num5;
  91. TextureScale.newColors[num4 + j] = TextureScale.ColorLerpUnclamped(TextureScale.ColorLerpUnclamped(TextureScale.texColors[num2 + num5], TextureScale.texColors[num2 + num5 + 1], value), TextureScale.ColorLerpUnclamped(TextureScale.texColors[num3 + num5], TextureScale.texColors[num3 + num5 + 1], value), (float)i * TextureScale.ratioY - (float)num);
  92. }
  93. }
  94. TextureScale.mutex.WaitOne();
  95. TextureScale.finishCount++;
  96. TextureScale.mutex.ReleaseMutex();
  97. }
  98. public static void PointScale(object obj)
  99. {
  100. TextureScale.ThreadData threadData = (TextureScale.ThreadData)obj;
  101. for (int i = threadData.start; i < threadData.end; i++)
  102. {
  103. int num = (int)(TextureScale.ratioY * (float)i) * TextureScale.w;
  104. int num2 = i * TextureScale.w2;
  105. for (int j = 0; j < TextureScale.w2; j++)
  106. {
  107. TextureScale.newColors[num2 + j] = TextureScale.texColors[(int)((float)num + TextureScale.ratioX * (float)j)];
  108. }
  109. }
  110. TextureScale.mutex.WaitOne();
  111. TextureScale.finishCount++;
  112. TextureScale.mutex.ReleaseMutex();
  113. }
  114. private static Color ColorLerpUnclamped(Color c1, Color c2, float value)
  115. {
  116. 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);
  117. }
  118. private static Color[] texColors;
  119. private static Color[] newColors;
  120. private static int w;
  121. private static float ratioX;
  122. private static float ratioY;
  123. private static int w2;
  124. private static int finishCount;
  125. private static Mutex mutex;
  126. public class ThreadData
  127. {
  128. public ThreadData(int s, int e)
  129. {
  130. this.start = s;
  131. this.end = e;
  132. }
  133. public int start;
  134. public int end;
  135. }
  136. }