diff --git a/Plugins/TextureOps/TextureOps.cs b/Plugins/TextureOps/TextureOps.cs index f23ac4d..7a4f9dc 100644 --- a/Plugins/TextureOps/TextureOps.cs +++ b/Plugins/TextureOps/TextureOps.cs @@ -247,6 +247,54 @@ public static bool SaveImage( byte[] sourceBytes, string imagePath ) #endregion #region Texture Operations + public static Texture2D Crop( Texture sourceTex, int leftOffset, int topOffset, int width, int height, TextureFormat format = TextureFormat.RGBA32, Options options = new Options() ) + { + if( sourceTex == null ) + throw new ArgumentException( "Parameter 'sourceTex' is null!" ); + + if( width <= 0 || width > sourceTex.width ) + width = sourceTex.width; + if( height <= 0 || height > sourceTex.height ) + height = sourceTex.height; + if( leftOffset <= 0 ) + leftOffset = 0; + else if( leftOffset + width > sourceTex.width ) + leftOffset = sourceTex.width - width; + if( topOffset <= 0 ) + topOffset = 0; + else if( topOffset + height > sourceTex.height ) + topOffset = sourceTex.height - height; + + Texture2D result = null; + + RenderTexture rt = RenderTexture.GetTemporary( sourceTex.width, sourceTex.height ); + RenderTexture activeRT = RenderTexture.active; + + try + { + Graphics.Blit( sourceTex, rt ); + RenderTexture.active = rt; + + result = new Texture2D( width, height, format, options.generateMipmaps, options.linearColorSpace ); + result.ReadPixels( new Rect( leftOffset, sourceTex.height - topOffset - height, width, height ), 0, 0, false ); + result.Apply( options.generateMipmaps, options.markNonReadable ); + } + catch( Exception e ) + { + Debug.LogException( e ); + + Object.Destroy( result ); + result = null; + } + finally + { + RenderTexture.active = activeRT; + RenderTexture.ReleaseTemporary( rt ); + } + + return result; + } + public static Texture2D Scale( Texture sourceTex, int targetWidth, int targetHeight, TextureFormat format = TextureFormat.RGBA32, Options options = new Options() ) { if( sourceTex == null ) @@ -329,7 +377,7 @@ public static bool SaveImage( byte[] sourceBytes, string imagePath ) return result; } - + public static Texture2D[] Slice( Texture sourceTex, int sliceTexWidth, int sliceTexHeight, TextureFormat format = TextureFormat.RGBA32, Options options = new Options() ) { if( sourceTex == null ) diff --git a/README.md b/README.md index 2972b94..4e09aba 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,8 @@ Simply import [TextureOps.unitypackage](https://github.com/yasirkula/UnityTextur **NOTE:** on some Android devices, these functions may not work correctly when called with a *sourceTex* that was created in the same frame. Therefore, if you'd like to call these functions immediately after *LoadImage*, consider instead waiting for at least one frame. You can use `yield return null;` in a coroutine to wait for one frame. +`Texture2D[] TextureOps.Crop( Texture2D, sourceTex, int leftOffset, int topOffset, int width, int height, TextureFormat format = TextureFormat.RGBA32, TextureOps.Options options )`: crops sourceTex and returns the cropped texture. + `Texture2D TextureOps.Scale( Texture2D sourceTex, int targetWidth, int targetHeight, TextureFormat format = TextureFormat.RGBA32, TextureOps.Options options )`: scales *sourceTex* to the specified size and returns the scaled texture. sourceTex's aspect ratio may not be preserved. `Texture2D TextureOps.ScaleFill( Texture2D sourceTex, int targetWidth, int targetHeight, Color32 fillColor, TextureFormat format = TextureFormat.RGBA32, TextureOps.Options options )`: scales *sourceTex* to the specified size and returns the scaled texture. sourceTex's aspect ratio is preserved and blank space is filled with *fillColor*.