TextureExtension.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. public static class TextureExtension
  5. {
  6. public struct Point
  7. {
  8. public short x;
  9. public short y;
  10. public Point(short aX, short aY) { x = aX; y = aY; }
  11. public Point(int aX, int aY) : this((short)aX, (short)aY) { }
  12. }
  13. public static void FloodFillArea(this Texture2D aTex, int aX, int aY, Color aFillColor)
  14. {
  15. int w = aTex.width;
  16. int h = aTex.height;
  17. Color[] colors = aTex.GetPixels();
  18. Color refCol = colors[aX + aY * w];
  19. Queue<Point> nodes = new Queue<Point>();
  20. nodes.Enqueue(new Point(aX, aY));
  21. while (nodes.Count > 0)
  22. {
  23. Point current = nodes.Dequeue();
  24. for (int i = current.x; i < w; i++)
  25. {
  26. Color C = colors[i + current.y * w];
  27. if (C != refCol || C == aFillColor)
  28. break;
  29. colors[i + current.y * w] = aFillColor;
  30. if (current.y + 1 < h)
  31. {
  32. C = colors[i + current.y * w + w];
  33. if (C == refCol && C != aFillColor)
  34. nodes.Enqueue(new Point(i, current.y + 1));
  35. }
  36. if (current.y - 1 >= 0)
  37. {
  38. C = colors[i + current.y * w - w];
  39. if (C == refCol && C != aFillColor)
  40. nodes.Enqueue(new Point(i, current.y - 1));
  41. }
  42. }
  43. for (int i = current.x - 1; i >= 0; i--)
  44. {
  45. Color C = colors[i + current.y * w];
  46. if (C != refCol || C == aFillColor)
  47. break;
  48. colors[i + current.y * w] = aFillColor;
  49. if (current.y + 1 < h)
  50. {
  51. C = colors[i + current.y * w + w];
  52. if (C == refCol && C != aFillColor)
  53. nodes.Enqueue(new Point(i, current.y + 1));
  54. }
  55. if (current.y - 1 >= 0)
  56. {
  57. C = colors[i + current.y * w - w];
  58. if (C == refCol && C != aFillColor)
  59. nodes.Enqueue(new Point(i, current.y - 1));
  60. }
  61. }
  62. }
  63. aTex.SetPixels(colors);
  64. }
  65. public static void FloodFillBorder(this Texture2D aTex, int aX, int aY, Color aFillColor, Color aBorderColor)
  66. {
  67. int w = aTex.width;
  68. int h = aTex.height;
  69. Color[] colors = aTex.GetPixels();
  70. byte[] checkedPixels = new byte[colors.Length];
  71. Color refCol = aBorderColor;
  72. Queue<Point> nodes = new Queue<Point>();
  73. nodes.Enqueue(new Point(aX, aY));
  74. while (nodes.Count > 0)
  75. {
  76. Point current = nodes.Dequeue();
  77. for (int i = current.x; i < w; i++)
  78. {
  79. if (checkedPixels[i + current.y * w] > 0 || colors[i + current.y * w] == refCol)
  80. break;
  81. colors[i + current.y * w] = aFillColor;
  82. checkedPixels[i + current.y * w] = 1;
  83. if (current.y + 1 < h)
  84. {
  85. if (checkedPixels[i + current.y * w + w] == 0 && colors[i + current.y * w + w] != refCol)
  86. nodes.Enqueue(new Point(i, current.y + 1));
  87. }
  88. if (current.y - 1 >= 0)
  89. {
  90. if (checkedPixels[i + current.y * w - w] == 0 && colors[i + current.y * w - w] != refCol)
  91. nodes.Enqueue(new Point(i, current.y - 1));
  92. }
  93. }
  94. for (int i = current.x - 1; i >= 0; i--)
  95. {
  96. if (checkedPixels[i + current.y * w] > 0 || colors[i + current.y * w] == refCol)
  97. break;
  98. colors[i + current.y * w] = aFillColor;
  99. checkedPixels[i + current.y * w] = 1;
  100. if (current.y + 1 < h)
  101. {
  102. if (checkedPixels[i + current.y * w + w] == 0 && colors[i + current.y * w + w] != refCol)
  103. nodes.Enqueue(new Point(i, current.y + 1));
  104. }
  105. if (current.y - 1 >= 0)
  106. {
  107. if (checkedPixels[i + current.y * w - w] == 0 && colors[i + current.y * w - w] != refCol)
  108. nodes.Enqueue(new Point(i, current.y - 1));
  109. }
  110. }
  111. }
  112. aTex.SetPixels(colors);
  113. }
  114. }