From cf67815d539efdb8905df8c4f4c0d42bc6971efe Mon Sep 17 00:00:00 2001 From: VaDiM Date: Fri, 25 Aug 2023 21:45:29 +0300 Subject: [PATCH] Minor fixes --- AssetStudioCLI/CLILogger.cs | 7 +- AssetStudioCLI/Exporter.cs | 84 ++++++++----- AssetStudioCLI/Options/CLIOptions.cs | 3 +- AssetStudioGUI/AboutForm.cs | 8 -- AssetStudioGUI/AssetStudioGUIForm.cs | 48 ++++---- AssetStudioUtility/SpriteHelper.cs | 173 ++++++++++++++------------- 6 files changed, 174 insertions(+), 149 deletions(-) diff --git a/AssetStudioCLI/CLILogger.cs b/AssetStudioCLI/CLILogger.cs index e74f29d..9aeac57 100644 --- a/AssetStudioCLI/CLILogger.cs +++ b/AssetStudioCLI/CLILogger.cs @@ -25,11 +25,12 @@ namespace AssetStudioCLI { logOutput = CLIOptions.o_logOutput.Value; logMinLevel = CLIOptions.o_logLevel.Value; - LogName = $"AssetStudioCLI_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.log"; + var appAssembly = typeof(Program).Assembly.GetName(); + LogName = $"{appAssembly.Name}_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.log"; LogPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, LogName); + var arch = Environment.Is64BitProcess ? "x64" : "x32"; - var ver = typeof(Program).Assembly.GetName().Version; - LogToFile(LoggerEvent.Verbose, $"---AssetStudioCLI v{ver} | Logger launched---\n" + + LogToFile(LoggerEvent.Verbose, $"---{appAssembly.Name} v{appAssembly.Version} [{arch}] | Logger launched---\n" + $"CMD Args: {string.Join(" ", CLIOptions.cliArgs)}"); } diff --git a/AssetStudioCLI/Exporter.cs b/AssetStudioCLI/Exporter.cs index 77cc99a..94ce07c 100644 --- a/AssetStudioCLI/Exporter.cs +++ b/AssetStudioCLI/Exporter.cs @@ -17,6 +17,30 @@ namespace AssetStudioCLI var type = CLIOptions.o_imageFormat.Value; if (!TryExportFile(exportPath, item, "." + type.ToString().ToLower(), out var exportFullPath)) return false; + + if (CLIOptions.o_logLevel.Value <= LoggerEvent.Debug) + { + var sb = new StringBuilder(); + sb.AppendLine($"Converting \"{m_Texture2D.m_Name}\" to {type}.."); + sb.AppendLine($"Width: {m_Texture2D.m_Width}"); + sb.AppendLine($"Height: {m_Texture2D.m_Height}"); + sb.AppendLine($"Format: {m_Texture2D.m_TextureFormat}"); + switch (m_Texture2D.m_TextureSettings.m_FilterMode) + { + case 0: sb.AppendLine("Filter Mode: Point "); break; + case 1: sb.AppendLine("Filter Mode: Bilinear "); break; + case 2: sb.AppendLine("Filter Mode: Trilinear "); break; + } + sb.AppendLine($"Anisotropic level: {m_Texture2D.m_TextureSettings.m_Aniso}"); + sb.AppendLine($"Mip map bias: {m_Texture2D.m_TextureSettings.m_MipBias}"); + switch (m_Texture2D.m_TextureSettings.m_WrapMode) + { + case 0: sb.AppendLine($"Wrap mode: Repeat"); break; + case 1: sb.AppendLine($"Wrap mode: Clamp"); break; + } + Logger.Debug(sb.ToString()); + } + var image = m_Texture2D.ConvertToImage(flip: true); if (image == null) { @@ -29,7 +53,7 @@ namespace AssetStudioCLI { image.WriteToStream(file, type); } - Logger.Debug($"{item.TypeString}: \"{item.Text}\" exported to \"{exportFullPath}\""); + Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\""); return true; } } @@ -38,7 +62,7 @@ namespace AssetStudioCLI if (!TryExportFile(exportPath, item, ".tex", out var exportFullPath)) return false; File.WriteAllBytes(exportFullPath, m_Texture2D.image_data.GetData()); - Logger.Debug($"{item.TypeString}: \"{item.Text}\" exported to \"{exportFullPath}\""); + Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\""); return true; } } @@ -59,13 +83,16 @@ namespace AssetStudioCLI if (!TryExportFile(exportPath, item, ".wav", out exportFullPath)) return false; - var sb = new StringBuilder(); - sb.AppendLine($"Converting \"{m_AudioClip.m_Name}\" to wav.."); - sb.AppendLine(m_AudioClip.version[0] < 5 ? $"AudioClip type: {m_AudioClip.m_Type}" : $"AudioClip compression format: {m_AudioClip.m_CompressionFormat}"); - sb.AppendLine($"AudioClip channel count: {m_AudioClip.m_Channels}"); - sb.AppendLine($"AudioClip sample rate: {m_AudioClip.m_Frequency}"); - sb.AppendLine($"AudioClip bit depth: {m_AudioClip.m_BitsPerSample}"); - Logger.Debug(sb.ToString()); + if (CLIOptions.o_logLevel.Value <= LoggerEvent.Debug) + { + var sb = new StringBuilder(); + sb.AppendLine($"Converting \"{m_AudioClip.m_Name}\" to wav.."); + sb.AppendLine(m_AudioClip.version[0] < 5 ? $"AudioClip type: {m_AudioClip.m_Type}" : $"AudioClip compression format: {m_AudioClip.m_CompressionFormat}"); + sb.AppendLine($"AudioClip channel count: {m_AudioClip.m_Channels}"); + sb.AppendLine($"AudioClip sample rate: {m_AudioClip.m_Frequency}"); + sb.AppendLine($"AudioClip bit depth: {m_AudioClip.m_BitsPerSample}"); + Logger.Debug(sb.ToString()); + } var buffer = converter.ConvertToWav(m_AudioData); if (buffer == null) @@ -82,7 +109,7 @@ namespace AssetStudioCLI File.WriteAllBytes(exportFullPath, m_AudioData); } - Logger.Debug($"{item.TypeString}: \"{item.Text}\" exported to \"{exportFullPath}\""); + Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\""); return true; } @@ -94,16 +121,19 @@ namespace AssetStudioCLI if (!TryExportFile(exportPath, item, Path.GetExtension(m_VideoClip.m_OriginalPath), out var exportFullPath)) return false; - var sb = new StringBuilder(); - sb.AppendLine($"VideoClip format: {m_VideoClip.m_Format}"); - sb.AppendLine($"VideoClip width: {m_VideoClip.Width}"); - sb.AppendLine($"VideoClip height: {m_VideoClip.Height}"); - sb.AppendLine($"VideoClip frame rate: {m_VideoClip.m_FrameRate}"); - sb.AppendLine($"VideoClip split alpha: {m_VideoClip.m_HasSplitAlpha}"); - Logger.Debug(sb.ToString()); + if (CLIOptions.o_logLevel.Value <= LoggerEvent.Debug) + { + var sb = new StringBuilder(); + sb.AppendLine($"VideoClip format: {m_VideoClip.m_Format}"); + sb.AppendLine($"VideoClip width: {m_VideoClip.Width}"); + sb.AppendLine($"VideoClip height: {m_VideoClip.Height}"); + sb.AppendLine($"VideoClip frame rate: {m_VideoClip.m_FrameRate:.0##}"); + sb.AppendLine($"VideoClip split alpha: {m_VideoClip.m_HasSplitAlpha}"); + Logger.Debug(sb.ToString()); + } m_VideoClip.m_VideoData.WriteData(exportFullPath); - Logger.Debug($"{item.TypeString}: \"{item.Text}\" exported to \"{exportFullPath}\""); + Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\""); return true; } return false; @@ -116,7 +146,7 @@ namespace AssetStudioCLI return false; File.WriteAllBytes(exportFullPath, m_MovieTexture.m_MovieData); - Logger.Debug($"{item.TypeString}: \"{item.Text}\" exported to \"{exportFullPath}\""); + Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\""); return true; } @@ -128,7 +158,7 @@ namespace AssetStudioCLI var str = m_Shader.Convert(); File.WriteAllText(exportFullPath, str); - Logger.Debug($"{item.TypeString}: \"{item.Text}\" exported to \"{exportFullPath}\""); + Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\""); return true; } @@ -156,7 +186,7 @@ namespace AssetStudioCLI return false; File.WriteAllBytes(exportFullPath, m_TextAsset.m_Script); - Logger.Debug($"{item.TypeString}: \"{item.Text}\" exported to \"{exportFullPath}\""); + Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\""); return true; } @@ -176,7 +206,7 @@ namespace AssetStudioCLI var str = JsonConvert.SerializeObject(type, Formatting.Indented); File.WriteAllText(exportFullPath, str); - Logger.Debug($"{item.TypeString}: \"{item.Text}\" exported to \"{exportFullPath}\""); + Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\""); return true; } return false; @@ -196,7 +226,7 @@ namespace AssetStudioCLI return false; File.WriteAllBytes(exportFullPath, m_Font.m_FontData); - Logger.Debug($"{item.TypeString}: \"{item.Text}\" exported to \"{exportFullPath}\""); + Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\""); return true; } return false; @@ -217,7 +247,7 @@ namespace AssetStudioCLI { image.WriteToStream(file, type); } - Logger.Debug($"{item.TypeString}: \"{item.Text}\" exported to \"{exportFullPath}\""); + Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\""); return true; } } @@ -230,7 +260,7 @@ namespace AssetStudioCLI return false; File.WriteAllBytes(exportFullPath, item.Asset.GetRawData()); - Logger.Debug($"{item.TypeString}: \"{item.Text}\" exported to \"{exportFullPath}\""); + Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\""); return true; } @@ -247,7 +277,7 @@ namespace AssetStudioCLI if (str != null) { File.WriteAllText(exportFullPath, str); - Logger.Debug($"{item.TypeString}: \"{item.Text}\" saved to \"{exportFullPath}\""); + Logger.Debug($"{item.TypeString} \"{item.Text}\" saved to \"{exportFullPath}\""); return true; } return false; @@ -365,7 +395,7 @@ namespace AssetStudioCLI sb.Replace("NaN", "0"); File.WriteAllText(exportFullPath, sb.ToString()); - Logger.Debug($"{item.TypeString}: \"{item.Text}\" exported to \"{exportFullPath}\""); + Logger.Debug($"{item.TypeString} \"{item.Text}\" exported to \"{exportFullPath}\""); return true; } diff --git a/AssetStudioCLI/Options/CLIOptions.cs b/AssetStudioCLI/Options/CLIOptions.cs index b1d87a6..f8b8de9 100644 --- a/AssetStudioCLI/Options/CLIOptions.cs +++ b/AssetStudioCLI/Options/CLIOptions.cs @@ -761,7 +761,8 @@ namespace AssetStudioCLI.Options } else { - Console.WriteLine($"# {appAssembly.Name}\n# Based on AssetStudioMod v{appAssembly.Version}\n"); + var arch = Environment.Is64BitProcess ? "x64" : "x32"; + Console.WriteLine($"# {appAssembly.Name} [{arch}]\n# Based on AssetStudioMod v{appAssembly.Version}\n"); Console.WriteLine($"{usage}\n\n{helpMessage}"); } } diff --git a/AssetStudioGUI/AboutForm.cs b/AssetStudioGUI/AboutForm.cs index baee692..307a60e 100644 --- a/AssetStudioGUI/AboutForm.cs +++ b/AssetStudioGUI/AboutForm.cs @@ -1,14 +1,6 @@ using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; using System.Diagnostics; -using System.Drawing; using System.IO; -using System.Linq; -using System.Reflection.Emit; -using System.Text; -using System.Threading.Tasks; using System.Windows.Forms; namespace AssetStudioGUI diff --git a/AssetStudioGUI/AssetStudioGUIForm.cs b/AssetStudioGUI/AssetStudioGUIForm.cs index 55db635..4186eff 100644 --- a/AssetStudioGUI/AssetStudioGUIForm.cs +++ b/AssetStudioGUI/AssetStudioGUIForm.cs @@ -1,6 +1,5 @@ using AssetStudio; using Newtonsoft.Json; -using OpenTK; using OpenTK.Graphics.OpenGL; using System; using System.Collections.Generic; @@ -21,6 +20,7 @@ using static AssetStudioGUI.Studio; using Font = AssetStudio.Font; using Microsoft.WindowsAPICodePack.Taskbar; #if NET472 +using OpenTK; using Vector3 = OpenTK.Vector3; using Vector4 = OpenTK.Vector4; #else @@ -785,42 +785,42 @@ namespace AssetStudioGUI return; try { - switch (assetItem.Asset) + switch (assetItem.Type) { - case Texture2D m_Texture2D: - PreviewTexture2D(assetItem, m_Texture2D); + case ClassIDType.Texture2D: + PreviewTexture2D(assetItem, assetItem.Asset as Texture2D); break; - case AudioClip m_AudioClip: - PreviewAudioClip(assetItem, m_AudioClip); + case ClassIDType.AudioClip: + PreviewAudioClip(assetItem, assetItem.Asset as AudioClip); break; - case Shader m_Shader: - PreviewShader(m_Shader); + case ClassIDType.Shader: + PreviewShader(assetItem.Asset as Shader); break; - case TextAsset m_TextAsset: - PreviewTextAsset(m_TextAsset); + case ClassIDType.TextAsset: + PreviewTextAsset(assetItem.Asset as TextAsset); break; - case MonoBehaviour m_MonoBehaviour: - PreviewMonoBehaviour(m_MonoBehaviour); + case ClassIDType.MonoBehaviour: + PreviewMonoBehaviour(assetItem.Asset as MonoBehaviour); break; - case Font m_Font: - PreviewFont(m_Font); + case ClassIDType.Font: + PreviewFont(assetItem.Asset as Font); break; - case Mesh m_Mesh: - PreviewMesh(m_Mesh); + case ClassIDType.Mesh: + PreviewMesh(assetItem.Asset as Mesh); break; - case VideoClip m_VideoClip: - PreviewVideoClip(assetItem, m_VideoClip); + case ClassIDType.VideoClip: + PreviewVideoClip(assetItem, assetItem.Asset as VideoClip); break; - case MovieTexture _: + case ClassIDType.MovieTexture: StatusStripUpdate("Only supported export."); break; - case Sprite m_Sprite: - PreviewSprite(assetItem, m_Sprite); + case ClassIDType.Sprite: + PreviewSprite(assetItem, assetItem.Asset as Sprite); break; - case Animator _: + case ClassIDType.Animator: StatusStripUpdate("Can be exported to FBX file."); break; - case AnimationClip _: + case ClassIDType.AnimationClip: StatusStripUpdate("Can be exported with Animator or Objects"); break; default: @@ -1029,7 +1029,7 @@ namespace AssetStudioGUI var sb = new StringBuilder(); sb.AppendLine($"Width: {m_VideoClip.Width}"); sb.AppendLine($"Height: {m_VideoClip.Height}"); - sb.AppendLine($"Frame rate: {m_VideoClip.m_FrameRate}"); + sb.AppendLine($"Frame rate: {m_VideoClip.m_FrameRate:.0##}"); sb.AppendLine($"Split alpha: {m_VideoClip.m_HasSplitAlpha}"); assetItem.InfoText = sb.ToString(); diff --git a/AssetStudioUtility/SpriteHelper.cs b/AssetStudioUtility/SpriteHelper.cs index 8d6d735..382bd08 100644 --- a/AssetStudioUtility/SpriteHelper.cs +++ b/AssetStudioUtility/SpriteHelper.cs @@ -34,7 +34,11 @@ namespace AssetStudio { if (m_Sprite.m_RD.texture.TryGet(out var m_Texture2D) && m_Sprite.m_RD.alphaTexture.TryGet(out var m_AlphaTexture2D) && spriteMaskMode != SpriteMaskMode.Off) { - var tex = CutImage(m_Sprite, m_Texture2D, m_Sprite.m_RD.textureRect, m_Sprite.m_RD.textureRectOffset, m_Sprite.m_RD.downscaleMultiplier, m_Sprite.m_RD.settingsRaw); + Image tex = null; + if (spriteMaskMode != SpriteMaskMode.MaskOnly) + { + tex = CutImage(m_Sprite, m_Texture2D, m_Sprite.m_RD.textureRect, m_Sprite.m_RD.textureRectOffset, m_Sprite.m_RD.downscaleMultiplier, m_Sprite.m_RD.settingsRaw); + } var alphaTex = CutImage(m_Sprite, m_AlphaTexture2D, m_Sprite.m_RD.textureRect, m_Sprite.m_RD.textureRectOffset, m_Sprite.m_RD.downscaleMultiplier, m_Sprite.m_RD.settingsRaw); switch (spriteMaskMode) @@ -46,7 +50,6 @@ namespace AssetStudio tex.ApplyRGBMask(alphaTex); return tex; case SpriteMaskMode.MaskOnly: - tex.Dispose(); return alphaTex; } } @@ -89,92 +92,90 @@ namespace AssetStudio var originalImage = m_Texture2D.ConvertToImage(false); if (originalImage != null) { - using (originalImage) + if (downscaleMultiplier > 0f && downscaleMultiplier != 1f) { - if (downscaleMultiplier > 0f && downscaleMultiplier != 1f) - { - var width = (int)(m_Texture2D.m_Width / downscaleMultiplier); - var height = (int)(m_Texture2D.m_Height / downscaleMultiplier); - originalImage.Mutate(x => x.Resize(width, height)); - } - var rectX = (int)Math.Floor(textureRect.x); - var rectY = (int)Math.Floor(textureRect.y); - var rectRight = (int)Math.Ceiling(textureRect.x + textureRect.width); - var rectBottom = (int)Math.Ceiling(textureRect.y + textureRect.height); - rectRight = Math.Min(rectRight, originalImage.Width); - rectBottom = Math.Min(rectBottom, originalImage.Height); - var rect = new Rectangle(rectX, rectY, rectRight - rectX, rectBottom - rectY); - var spriteImage = originalImage.Clone(x => x.Crop(rect)); - if (settingsRaw.packed == 1) - { - //RotateAndFlip - switch (settingsRaw.packingRotation) - { - case SpritePackingRotation.FlipHorizontal: - spriteImage.Mutate(x => x.Flip(FlipMode.Horizontal)); - break; - case SpritePackingRotation.FlipVertical: - spriteImage.Mutate(x => x.Flip(FlipMode.Vertical)); - break; - case SpritePackingRotation.Rotate180: - spriteImage.Mutate(x => x.Rotate(180)); - break; - case SpritePackingRotation.Rotate90: - spriteImage.Mutate(x => x.Rotate(270)); - break; - } - } - - //Tight - if (settingsRaw.packingMode == SpritePackingMode.Tight) - { - try - { - var matrix = Matrix3x2.CreateScale(m_Sprite.m_PixelsToUnits); - matrix *= Matrix3x2.CreateTranslation(m_Sprite.m_Rect.width * m_Sprite.m_Pivot.X - textureRectOffset.X, m_Sprite.m_Rect.height * m_Sprite.m_Pivot.Y - textureRectOffset.Y); - var triangles = GetTriangles(m_Sprite.m_RD); - var points = triangles.Select(x => x.Select(y => new PointF(y.X, y.Y)).ToArray()); - var pathBuilder = new PathBuilder(matrix); - foreach (var p in points) - { - pathBuilder.AddLines(p); - pathBuilder.CloseFigure(); - } - var path = pathBuilder.Build(); - var options = new DrawingOptions - { - GraphicsOptions = new GraphicsOptions - { - Antialias = false, - AlphaCompositionMode = PixelAlphaCompositionMode.DestOut - } - }; - if (triangles.Length < 1024) - { - var rectP = new RectangularPolygon(0, 0, rect.Width, rect.Height); - spriteImage.Mutate(x => x.Fill(options, SixLabors.ImageSharp.Color.Red, rectP.Clip(path))); - spriteImage.Mutate(x => x.Flip(FlipMode.Vertical)); - return spriteImage; - } - using (var mask = new Image(rect.Width, rect.Height, SixLabors.ImageSharp.Color.Black)) - { - mask.Mutate(x => x.Fill(options, SixLabors.ImageSharp.Color.Red, path)); - var brush = new ImageBrush(mask); - spriteImage.Mutate(x => x.Fill(options, brush)); - spriteImage.Mutate(x => x.Flip(FlipMode.Vertical)); - return spriteImage; - } - } - catch - { - // ignored - } - } - - //Rectangle - spriteImage.Mutate(x => x.Flip(FlipMode.Vertical)); - return spriteImage; + var width = (int)(m_Texture2D.m_Width / downscaleMultiplier); + var height = (int)(m_Texture2D.m_Height / downscaleMultiplier); + originalImage.Mutate(x => x.Resize(width, height)); } + var rectX = (int)Math.Floor(textureRect.x); + var rectY = (int)Math.Floor(textureRect.y); + var rectRight = (int)Math.Ceiling(textureRect.x + textureRect.width); + var rectBottom = (int)Math.Ceiling(textureRect.y + textureRect.height); + rectRight = Math.Min(rectRight, originalImage.Width); + rectBottom = Math.Min(rectBottom, originalImage.Height); + var rect = new Rectangle(rectX, rectY, rectRight - rectX, rectBottom - rectY); + var spriteImage = originalImage.Clone(x => x.Crop(rect)); + originalImage.Dispose(); + if (settingsRaw.packed == 1) + { + //RotateAndFlip + switch (settingsRaw.packingRotation) + { + case SpritePackingRotation.FlipHorizontal: + spriteImage.Mutate(x => x.Flip(FlipMode.Horizontal)); + break; + case SpritePackingRotation.FlipVertical: + spriteImage.Mutate(x => x.Flip(FlipMode.Vertical)); + break; + case SpritePackingRotation.Rotate180: + spriteImage.Mutate(x => x.Rotate(180)); + break; + case SpritePackingRotation.Rotate90: + spriteImage.Mutate(x => x.Rotate(270)); + break; + } + } + + //Tight + if (settingsRaw.packingMode == SpritePackingMode.Tight) + { + try + { + var matrix = Matrix3x2.CreateScale(m_Sprite.m_PixelsToUnits); + matrix *= Matrix3x2.CreateTranslation(m_Sprite.m_Rect.width * m_Sprite.m_Pivot.X - textureRectOffset.X, m_Sprite.m_Rect.height * m_Sprite.m_Pivot.Y - textureRectOffset.Y); + var triangles = GetTriangles(m_Sprite.m_RD); + var points = triangles.Select(x => x.Select(y => new PointF(y.X, y.Y)).ToArray()); + var pathBuilder = new PathBuilder(matrix); + foreach (var p in points) + { + pathBuilder.AddLines(p); + pathBuilder.CloseFigure(); + } + var path = pathBuilder.Build(); + var options = new DrawingOptions + { + GraphicsOptions = new GraphicsOptions + { + Antialias = false, + AlphaCompositionMode = PixelAlphaCompositionMode.DestOut + } + }; + if (triangles.Length < 1024) + { + var rectP = new RectangularPolygon(0, 0, rect.Width, rect.Height); + spriteImage.Mutate(x => x.Fill(options, SixLabors.ImageSharp.Color.Red, rectP.Clip(path))); + spriteImage.Mutate(x => x.Flip(FlipMode.Vertical)); + return spriteImage; + } + using (var mask = new Image(rect.Width, rect.Height, SixLabors.ImageSharp.Color.Black)) + { + mask.Mutate(x => x.Fill(options, SixLabors.ImageSharp.Color.Red, path)); + var brush = new ImageBrush(mask); + spriteImage.Mutate(x => x.Fill(options, brush)); + spriteImage.Mutate(x => x.Flip(FlipMode.Vertical)); + return spriteImage; + } + } + catch + { + // ignored + } + } + + //Rectangle + spriteImage.Mutate(x => x.Flip(FlipMode.Vertical)); + return spriteImage; } return null;