diff --git a/doc/KKAPI.Utilities.md b/doc/KKAPI.Utilities.md
index 1a7ecb9..692db51 100644
--- a/doc/KKAPI.Utilities.md
+++ b/doc/KKAPI.Utilities.md
@@ -288,6 +288,7 @@ Static Methods
| Type | Name | Summary |
| --- | --- | --- |
| `Texture2D` | LoadTexture(this `Byte[]` texBytes, `TextureFormat` format = ARGB32, `Boolean` mipMaps = False) | Create texture from an image stored in a byte array, for example a png file read from disk. |
+| `Texture2D` | ResizeTexture(this `Texture2D` pSource, `ImageFilterMode` pFilterMode, `Single` pScale) | Create a resized copy of this texture. http://blog.collectivemass.com/2014/03/resizing-textures-in-unity/ |
| `Sprite` | ToSprite(this `Texture2D` texture) | Create a sprite based on this texture. |
| `Texture2D` | ToTexture2D(this `Texture` tex, `TextureFormat` format = ARGB32, `Boolean` mipMaps = False) | Copy this texture inside a new editable Texture2D. |
diff --git a/src/Shared.Core/Utilities/TextureUtils.cs b/src/Shared.Core/Utilities/TextureUtils.cs
index b4b25f2..c4865aa 100644
--- a/src/Shared.Core/Utilities/TextureUtils.cs
+++ b/src/Shared.Core/Utilities/TextureUtils.cs
@@ -53,5 +53,144 @@ public static Sprite ToSprite(this Texture2D texture)
if (texture == null) throw new ArgumentNullException(nameof(texture));
return Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));
}
+
+ ///
+ /// Filtering to use when resizing a texture
+ ///
+ public enum ImageFilterMode
+ {
+ ///
+ /// Nearest pixel, fastest but gets aliased
+ ///
+ Nearest = 0,
+ ///
+ /// Use bilinear scaling
+ ///
+ Biliner = 1,
+ ///
+ /// Average of all nearby pixels
+ ///
+ Average = 2
+ }
+
+ ///
+ /// Create a resized copy of this texture.
+ /// http://blog.collectivemass.com/2014/03/resizing-textures-in-unity/
+ ///
+ /// Texture to resize
+ /// How to resize
+ /// New scale
+ public static Texture2D ResizeTexture(this Texture2D pSource, ImageFilterMode pFilterMode, float pScale)
+ {
+ //*** Variables
+ int i;
+
+ //*** Get All the source pixels
+ Color[] aSourceColor = pSource.GetPixels(0);
+ Vector2 vSourceSize = new Vector2(pSource.width, pSource.height);
+
+ //*** Calculate New Size
+ float xWidth = Mathf.RoundToInt((float)pSource.width * pScale);
+ float xHeight = Mathf.RoundToInt((float)pSource.height * pScale);
+
+ //*** Make New
+ Texture2D oNewTex = new Texture2D((int)xWidth, (int)xHeight, TextureFormat.RGBA32, false);
+
+ //*** Make destination array
+ int xLength = (int)xWidth * (int)xHeight;
+ Color[] aColor = new Color[xLength];
+
+ Vector2 vPixelSize = new Vector2(vSourceSize.x / xWidth, vSourceSize.y / xHeight);
+
+ //*** Loop through destination pixels and process
+ Vector2 vCenter = new Vector2();
+ for (i = 0; i < xLength; i++)
+ {
+
+ //*** Figure out x&y
+ float xX = (float)i % xWidth;
+ float xY = Mathf.Floor((float)i / xWidth);
+
+ //*** Calculate Center
+ vCenter.x = (xX / xWidth) * vSourceSize.x;
+ vCenter.y = (xY / xHeight) * vSourceSize.y;
+
+ //*** Do Based on mode
+ //*** Nearest neighbour (testing)
+ if (pFilterMode == ImageFilterMode.Nearest)
+ {
+
+ //*** Nearest neighbour (testing)
+ vCenter.x = Mathf.Round(vCenter.x);
+ vCenter.y = Mathf.Round(vCenter.y);
+
+ //*** Calculate source index
+ int xSourceIndex = (int)((vCenter.y * vSourceSize.x) + vCenter.x);
+
+ //*** Copy Pixel
+ aColor[i] = aSourceColor[xSourceIndex];
+ }
+
+ //*** Bilinear
+ else if (pFilterMode == ImageFilterMode.Biliner)
+ {
+
+ //*** Get Ratios
+ float xRatioX = vCenter.x - Mathf.Floor(vCenter.x);
+ float xRatioY = vCenter.y - Mathf.Floor(vCenter.y);
+
+ //*** Get Pixel index's
+ int xIndexTL = (int)((Mathf.Floor(vCenter.y) * vSourceSize.x) + Mathf.Floor(vCenter.x));
+ int xIndexTR = (int)((Mathf.Floor(vCenter.y) * vSourceSize.x) + Mathf.Ceil(vCenter.x));
+ int xIndexBL = (int)((Mathf.Ceil(vCenter.y) * vSourceSize.x) + Mathf.Floor(vCenter.x));
+ int xIndexBR = (int)((Mathf.Ceil(vCenter.y) * vSourceSize.x) + Mathf.Ceil(vCenter.x));
+
+ //*** Calculate Color
+ aColor[i] = Color.Lerp(
+ Color.Lerp(aSourceColor[xIndexTL], aSourceColor[xIndexTR], xRatioX),
+ Color.Lerp(aSourceColor[xIndexBL], aSourceColor[xIndexBR], xRatioX),
+ xRatioY
+ );
+ }
+
+ //*** Average
+ else if (pFilterMode == ImageFilterMode.Average)
+ {
+
+ //*** Calculate grid around point
+ int xXFrom = (int)Mathf.Max(Mathf.Floor(vCenter.x - (vPixelSize.x * 0.5f)), 0);
+ int xXTo = (int)Mathf.Min(Mathf.Ceil(vCenter.x + (vPixelSize.x * 0.5f)), vSourceSize.x);
+ int xYFrom = (int)Mathf.Max(Mathf.Floor(vCenter.y - (vPixelSize.y * 0.5f)), 0);
+ int xYTo = (int)Mathf.Min(Mathf.Ceil(vCenter.y + (vPixelSize.y * 0.5f)), vSourceSize.y);
+
+ //*** Loop and accumulate
+ Vector4 oColorTotal = new Vector4();
+ Color oColorTemp = new Color();
+ float xGridCount = 0;
+ for (int iy = xYFrom; iy < xYTo; iy++)
+ {
+ for (int ix = xXFrom; ix < xXTo; ix++)
+ {
+
+ //*** Get Color
+ oColorTemp += aSourceColor[(int)(((float)iy * vSourceSize.x) + ix)];
+
+ //*** Sum
+ xGridCount++;
+ }
+ }
+
+ //*** Average Color
+ aColor[i] = oColorTemp / (float)xGridCount;
+ }
+ }
+
+ //*** Set Pixels
+ oNewTex.SetPixels(aColor);
+ oNewTex.Apply();
+
+ //*** Return
+ return oNewTex;
+ }
}
}