码迷,mamicode.com
首页 > 编程语言 > 详细

Unity图片处理类,包括压缩、截屏和滤镜

时间:2015-03-13 15:58:08      阅读:2391      评论:0      收藏:0      [点我收藏+]

标签:

  先上代码:
1
using System.Threading; 2 using UnityEngine; 3 using System.IO; 4 using System.Collections; 5 6 public class TextureUtility 7 { 8 public class ThreadData 9 { 10 public int start; 11 public int end; 12 public ThreadData (int s, int e) { 13 start = s; 14 end = e; 15 } 16 } 17 18 private static Color[] texColors; 19 private static Color[] newColors; 20 private static int w; 21 private static float ratioX; 22 private static float ratioY; 23 private static int w2; 24 private static int finishCount; 25 private static Mutex mutex; 26 27 public static void ScalePoint (Texture2D tex, int newWidth, int newHeight) 28 { 29 ThreadedScale (tex, newWidth, newHeight, false); 30 } 31 32 public static void ScaleBilinear (Texture2D tex, int newWidth, int newHeight) 33 { 34 ThreadedScale (tex, newWidth, newHeight, true); 35 } 36 37 private static void ThreadedScale (Texture2D tex, int newWidth, int newHeight, bool useBilinear) 38 { 39 texColors = tex.GetPixels(); 40 newColors = new Color[newWidth * newHeight]; 41 if (useBilinear) 42 { 43 ratioX = 1.0f / ((float)newWidth / (tex.width-1)); 44 ratioY = 1.0f / ((float)newHeight / (tex.height-1)); 45 } 46 else { 47 ratioX = ((float)tex.width) / newWidth; 48 ratioY = ((float)tex.height) / newHeight; 49 } 50 w = tex.width; 51 w2 = newWidth; 52 var cores = Mathf.Min(SystemInfo.processorCount, newHeight); 53 var slice = newHeight/cores; 54 55 finishCount = 0; 56 if (mutex == null) { 57 mutex = new Mutex(false); 58 } 59 if (cores > 1) 60 { 61 int i = 0; 62 ThreadData threadData; 63 for (i = 0; i < cores-1; i++) { 64 threadData = new ThreadData(slice * i, slice * (i + 1)); 65 ParameterizedThreadStart ts = useBilinear ? new ParameterizedThreadStart(BilinearScale) : new ParameterizedThreadStart(PointScale); 66 Thread thread = new Thread(ts); 67 thread.Start(threadData); 68 } 69 threadData = new ThreadData(slice*i, newHeight); 70 if (useBilinear) 71 { 72 BilinearScale(threadData); 73 } 74 else 75 { 76 PointScale(threadData); 77 } 78 while (finishCount < cores) 79 { 80 Thread.Sleep(1); 81 } 82 } 83 else 84 { 85 ThreadData threadData = new ThreadData(0, newHeight); 86 if (useBilinear) 87 { 88 BilinearScale(threadData); 89 } 90 else 91 { 92 PointScale(threadData); 93 } 94 } 95 96 tex.Resize(newWidth, newHeight); 97 tex.SetPixels(newColors); 98 tex.Apply(); 99 } 100 101 public static void BilinearScale (System.Object obj) 102 { 103 ThreadData threadData = (ThreadData) obj; 104 for (var y = threadData.start; y < threadData.end; y++) 105 { 106 int yFloor = (int)Mathf.Floor(y * ratioY); 107 var y1 = yFloor * w; 108 var y2 = (yFloor+1) * w; 109 var yw = y * w2; 110 111 for (var x = 0; x < w2; x++) { 112 int xFloor = (int)Mathf.Floor(x * ratioX); 113 var xLerp = x * ratioX-xFloor; 114 newColors[yw + x] = ColorLerpUnclamped(ColorLerpUnclamped(texColors[y1 + xFloor], texColors[y1 + xFloor+1], xLerp), 115 ColorLerpUnclamped(texColors[y2 + xFloor], texColors[y2 + xFloor+1], xLerp), 116 y*ratioY-yFloor); 117 } 118 } 119 120 mutex.WaitOne(); 121 finishCount++; 122 mutex.ReleaseMutex(); 123 } 124 125 public static void PointScale (System.Object obj) 126 { 127 ThreadData threadData = (ThreadData) obj; 128 for (var y = threadData.start; y < threadData.end; y++) 129 { 130 var thisY = (int)(ratioY * y) * w; 131 var yw = y * w2; 132 for (var x = 0; x < w2; x++) { 133 newColors[yw + x] = texColors[(int)(thisY + ratioX*x)]; 134 } 135 } 136 137 mutex.WaitOne(); 138 finishCount++; 139 mutex.ReleaseMutex(); 140 } 141 142 private static Color ColorLerpUnclamped (Color c1, Color c2, float value) 143 { 144 return new Color (c1.r + (c2.r - c1.r)*value, 145 c1.g + (c2.g - c1.g)*value, 146 c1.b + (c2.b - c1.b)*value, 147 c1.a + (c2.a - c1.a)*value); 148 } 149 150 public static Texture2D LoadTexture(string filePath) { 151 Texture2D tex = null; 152 byte[] fileData; 153 154 if (File.Exists(filePath)) { 155 fileData = File.ReadAllBytes(filePath); 156 tex = new Texture2D(2, 2,TextureFormat.ARGB32,false); 157 tex.LoadImage(fileData); 158 } 159 return tex; 160 } 161 162 // Save ScreenShot 163 164 public static void SaveScreenShotAsync(string path, Vector2 size) 165 { 166 SWMain.sharedSWMain.StartCoroutine(TextureUtility.SaveScreenShot(path, size)); 167 } 168 169 public static void SaveScreenShotAsync(string path, Rect rect, Vector2 size) 170 { 171 SWMain.sharedSWMain.StartCoroutine(TextureUtility.SaveScreenShot(path, rect, size)); 172 } 173 174 public static IEnumerator SaveScreenShot(string path, Vector2 size) 175 { 176 Rect rect = new Rect (0, 0, Screen.width, Screen.height); 177 yield return SWMain.sharedSWMain.StartCoroutine(TextureUtility.SaveScreenShot(path,rect, size)); 178 } 179 180 public static IEnumerator SaveScreenShot(string path, Rect rect, Vector2 size = default(Vector2)) 181 { 182 // We should only read the screen bufferafter rendering is complete 183 yield return new WaitForEndOfFrame(); 184 // 要保存图片的大小 185 Texture2D tex = new Texture2D ((int)rect.width, (int)rect.height, TextureFormat.RGB24, false); 186 // 截取的区域 187 tex.ReadPixels(rect, 0, 0); 188 tex.Apply(); 189 // 把图片数据转换为byte数组 190 if (size != default(Vector2)) 191 { 192 ScaleBilinear(tex, (int)size.x, (int)size.y); 193 } 194 195 byte[] buffer = tex.EncodeToJPG (100); 196 Object.Destroy(tex); 197 // 然后保存为图片 198 File.WriteAllBytes(path, buffer); 199 } 200 201 public static Texture2D Copy(Texture2D tex) 202 { 203 return new Texture2D(tex.width, tex.height, tex.format, false); 204 } 205 206 /// <summary> 207 /// Applies sepia effect to the texture. 208 /// </summary> 209 /// <param name="tex"> Texture to process.</param> 210 public static Texture2D SetSepia(Texture2D tex) 211 { 212 Texture2D t = Copy(tex); 213 Color[] colors = tex.GetPixels(); 214 215 for (int i = 0; i < colors.Length; i++) 216 { 217 float alpha = colors[i].a; 218 float grayScale = ((colors[i].r * .299f) + (colors[i].g * .587f) + (colors[i].b * .114f)); 219 Color c = new Color(grayScale, grayScale, grayScale); 220 colors[i] = new Color(c.r * 1, c.g * 0.95f, c.b * 0.82f, alpha); 221 } 222 t.SetPixels(colors); 223 t.Apply(); 224 return t; 225 } 226 227 /// <summary> 228 /// Applies grayscale effect to the texture and changes colors to grayscale. 229 /// </summary> 230 /// <param name="tex"> Texture to process.</param> 231 public static Texture2D SetGrayscale(Texture2D tex) 232 { 233 Texture2D t = Copy(tex); 234 235 Color[] colors = tex.GetPixels(); 236 for (int i = 0; i < colors.Length; i++) 237 { 238 float val = (colors [i].r + colors [i].g + colors [i].b) / 3; 239 colors [i] = new Color(val, val, val); 240 } 241 t.SetPixels(colors); 242 t.Apply(); 243 return t; 244 } 245 246 /// <summary> 247 /// Pixelates the texture. 248 /// </summary> 249 /// <param name="tex"> Texture to process.</param> 250 /// <param name="size"> Size of the pixel.</param> 251 public static Texture2D SetPixelate(Texture2D tex, int size) 252 { 253 Texture2D t = Copy(tex); 254 Rect rectangle = new Rect(0, 0, tex.width, tex.height); 255 for (int xx = (int)rectangle.x; xx < rectangle.x + rectangle.width && xx < tex.width; xx += size) 256 { 257 for (int yy = (int)rectangle.y; yy < rectangle.y + rectangle.height && yy < tex.height; yy += size) 258 { 259 int offsetX = size / 2; 260 int offsetY = size / 2; 261 while (xx + offsetX >= tex.width) offsetX--; 262 while (yy + offsetY >= tex.height) offsetY--; 263 Color pixel = tex.GetPixel(xx + offsetX, yy + offsetY); 264 for (int x = xx; x < xx + size && x < tex.width; x++) 265 for (int y = yy; y < yy + size && y < tex.height; y++) 266 t.SetPixel(x, y, pixel); 267 } 268 } 269 270 t.Apply(); 271 return t; 272 } 273 274 /// <summary> 275 /// Inverts colors of the texture. 276 /// </summary> 277 /// <param name="tex"> Texture to process.</param> 278 public static Texture2D SetNegative(Texture2D tex) 279 { 280 Texture2D t = Copy(tex); 281 Color[] colors = tex.GetPixels(); 282 Color pixel; 283 284 for (int i = 0; i < colors.Length; i++) 285 { 286 pixel = colors[i]; 287 colors[i] = new Color(1 - pixel.r, 1 - pixel.g, 1 - pixel.b); 288 } 289 t.SetPixels(colors); 290 t.Apply(); 291 return t; 292 } 293 294 /// <summary> 295 /// Sets the foggy effect.雾化效果 296 /// </summary> 297 /// <returns>texture processed.</returns> 298 /// <param name="tex">texture to process.</param> 299 public static Texture2D SetFoggy(Texture2D tex) 300 { 301 Texture2D t = Copy(tex); 302 Color pixel; 303 304 for (int x = 1; x < tex.width - 1; x++) 305 for (int y = 1; y < tex.height - 1; y++) 306 { 307 int k = UnityEngine.Random.Range(0, 123456); 308 //像素块大小 309 int dx = x + k % 19; 310 int dy = y + k % 19; 311 if (dx >= tex.width) 312 dx = tex.width - 1; 313 if (dy >= tex.height) 314 dy = tex.height - 1; 315 pixel = tex.GetPixel(dx, dy); 316 t.SetPixel(x, y, pixel); 317 } 318 319 t.Apply(); 320 321 return t; 322 } 323 324 /// <summary> 325 /// Sets the soft effect.柔化效果 326 /// </summary> 327 /// <returns>texture processed.</returns> 328 /// <param name="tex">texture to process.</param> 329 public static Texture2D SetSoft(Texture2D tex) 330 { 331 Texture2D t = Copy(tex); 332 int[] Gauss = { 1, 2, 1, 2, 4, 2, 1, 2, 1 }; 333 for (int x = 1; x < tex.width - 1; x++) 334 for (int y = 1; y < tex.height - 1; y++) 335 { 336 float r = 0, g = 0, b = 0; 337 int Index = 0; 338 for (int col = -1; col <= 1; col++) 339 for (int row = -1; row <= 1; row++) 340 { 341 Color pixel = tex.GetPixel(x + row, y + col); 342 r += pixel.r * Gauss[Index]; 343 g += pixel.g * Gauss[Index]; 344 b += pixel.b * Gauss[Index]; 345 Index++; 346 } 347 r /= 16; 348 g /= 16; 349 b /= 16; 350 //处理颜色值溢出 351 r = r > 1 ? 1 : r; 352 r = r < 0 ? 0 : r; 353 g = g > 1 ? 1 : g; 354 g = g < 0 ? 0 : g; 355 b = b > 1 ? 1 : b; 356 b = b < 0 ? 0 : b; 357 t.SetPixel(x - 1, y - 1, new Color(r, g, b)); 358 } 359 360 t.Apply(); 361 362 return t; 363 } 364 365 /// <summary> 366 /// Sets the sharp.锐化效果 367 /// </summary> 368 /// <returns>The sharp.</returns> 369 /// <param name="tex">Tex.</param> 370 public static Texture2D SetSharp(Texture2D tex) 371 { 372 Texture2D t = Copy(tex); 373 Color pixel; 374 //拉普拉斯模板 375 int[] Laplacian ={ -1, -1, -1, -1, 9, -1, -1, -1, -1 }; 376 for (int x = 1; x < tex.width - 1; x++) 377 for (int y = 1; y < tex.height - 1; y++) 378 { 379 float r = 0, g = 0, b = 0; 380 int index = 0; 381 for (int col = -1; col <= 1; col++) 382 for (int row = -1; row <= 1; row++) 383 { 384 pixel = tex.GetPixel(x + row, y + col); r += pixel.r * Laplacian[index]; 385 g += pixel.g * Laplacian[index]; 386 b += pixel.b * Laplacian[index]; 387 index++; 388 } 389 //处理颜色值溢出 390 r = r > 1 ? 1 : r; 391 r = r < 0 ? 0 : r; 392 g = g > 1 ? 1 : g; 393 g = g < 0 ? 0 : g; 394 b = b > 1 ? 1 : b; 395 b = b < 0 ? 0 : b; 396 t.SetPixel(x - 1, y - 1, new Color(r, g, b)); 397 } 398 399 t.Apply(); 400 return t; 401 } 402 403 /// <summary> 404 /// Sets the relief.浮雕效果 405 /// </summary> 406 /// <returns>The relief.</returns> 407 /// <param name="tex">Tex.</param> 408 public static Texture2D SetRelief(Texture2D tex) 409 { 410 Texture2D t = Copy(tex); 411 412 for (int x = 0; x < tex.width - 1; x++) 413 { 414 for (int y = 0; y < tex.height - 1; y++) 415 { 416 float r = 0, g = 0, b = 0; 417 Color pixel1 = tex.GetPixel(x, y); 418 Color pixel2 = tex.GetPixel(x + 1, y + 1); 419 r = Mathf.Abs(pixel1.r - pixel2.r + 0.5f); 420 g = Mathf.Abs(pixel1.g - pixel2.g + 0.5f); 421 b = Mathf.Abs(pixel1.b - pixel2.b + 0.5f); 422 if (r > 1) 423 r = 1; 424 if (r < 0) 425 r = 0; 426 if (g > 1) 427 g = 1; 428 if (g < 0) 429 g = 0; 430 if (b > 1) 431 b = 1; 432 if (b < 0) 433 b = 0; 434 t.SetPixel(x, y, new Color(r, g, b)); 435 } 436 } 437 438 t.Apply(); 439 return t; 440 } 441 442 }
如何调用:
1. 压缩图片:
  TextureUtility.ScalePoint(Texture2D tex, int newWidth, int newHeight),第一个参数是要传入的Texture2D, 第二个参数是新的图片的宽度,第三个参数则是新的图片的高度。也可以调用TextureUtility.ScaleBilinear(Texture2D tex, int newWidth, int newHeight)。
2. 截屏:
yield return StartCoroutine(TextureUtility.SaveScreenShot(string path, Vector2 size, Vector2 size = default(Vector2)))
或者调用异步方法TextureUtility.SaveScreenShotAsync(string path, Rect rect, Vector2 size)
3. 图片滤镜:
如灰阶滤镜:TextureUtility.SetGrayscale(Texture2D tex);
底片滤镜:TextureUtility.SetNegative(Texture2D tex)等。
    


 

Unity图片处理类,包括压缩、截屏和滤镜

标签:

原文地址:http://www.cnblogs.com/EndOfYear/p/4334952.html

(1)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!