Some refactor for Texture2DExtensions

This commit is contained in:
VaDiM
2026-01-27 00:05:45 +03:00
parent abeb251488
commit bb1cba89e1
6 changed files with 154 additions and 158 deletions
@@ -275,11 +275,14 @@ namespace CubismLive2DExtractor
return;
}
using (var image = texture2D.ConvertToImage(flip: true))
if (texture2D.TryConvertToImage(flip: true, out var image))
{
using (var file = File.OpenWrite(savePath))
{
image.WriteToStream(file, ImageFormat.Png);
using (image)
{
image.WriteToStream(file, ImageFormat.Png);
}
}
textureBag.Add($"textures/{texture2D.m_Name}.png");
}
+80 -82
View File
@@ -89,103 +89,101 @@ namespace AssetStudio
private static Image<Bgra32> CutImage(Sprite m_Sprite, Texture2D m_Texture2D, Rectf textureRect, Vector2 textureRectOffset, float downscaleMultiplier, SpriteSettings settingsRaw)
{
var originalImage = m_Texture2D.ConvertToImage(false);
if (originalImage != null)
{
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)MathF.Floor(textureRect.x);
var rectY = (int)MathF.Floor(textureRect.y);
var rectRight = (int)MathF.Ceiling(textureRect.x + textureRect.width);
var rectBottom = (int)MathF.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;
}
}
if (!m_Texture2D.TryConvertToImage(false, out var textureImage))
return null;
//Tight
if (settingsRaw.packingMode == SpritePackingMode.Tight)
if (downscaleMultiplier > 0f && downscaleMultiplier != 1f)
{
var width = (int)(m_Texture2D.m_Width / downscaleMultiplier);
var height = (int)(m_Texture2D.m_Height / downscaleMultiplier);
textureImage.Mutate(x => x.Resize(width, height));
}
var rectX = (int)MathF.Floor(textureRect.x);
var rectY = (int)MathF.Floor(textureRect.y);
var rectRight = (int)MathF.Ceiling(textureRect.x + textureRect.width);
var rectBottom = (int)MathF.Ceiling(textureRect.y + textureRect.height);
rectRight = Math.Min(rectRight, textureImage.Width);
rectBottom = Math.Min(rectBottom, textureImage.Height);
var rect = new Rectangle(rectX, rectY, rectRight - rectX, rectBottom - rectY);
var spriteImage = textureImage.Clone(x => x.Crop(rect));
textureImage.Dispose();
if (settingsRaw.packed == 1)
{
//RotateAndFlip
switch (settingsRaw.packingRotation)
{
try
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)));
var pathBuilder = new PathBuilder(matrix);
foreach (var p in points)
{
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)));
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
{
pathBuilder.AddLines(p);
pathBuilder.CloseFigure();
Antialias = false,
AlphaCompositionMode = PixelAlphaCompositionMode.DestOut
}
var path = pathBuilder.Build();
var options = new DrawingOptions
};
if (triangles.Length < 1024)
{
var rectP = new RectangularPolygon(0, 0, rect.Width, rect.Height);
try
{
GraphicsOptions = new GraphicsOptions
{
Antialias = false,
AlphaCompositionMode = PixelAlphaCompositionMode.DestOut
}
};
if (triangles.Length < 1024)
{
var rectP = new RectangularPolygon(0, 0, rect.Width, rect.Height);
try
{
spriteImage.Mutate(x => x.Fill(options, SixLabors.ImageSharp.Color.Red, rectP.Clip(path.Clip())));
spriteImage.Mutate(x => x.Flip(FlipMode.Vertical));
return spriteImage;
}
catch (ArgumentOutOfRangeException)
{
// ignored
}
}
using (var mask = new Image<Bgra32>(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.Fill(options, SixLabors.ImageSharp.Color.Red, rectP.Clip(path.Clip())));
spriteImage.Mutate(x => x.Flip(FlipMode.Vertical));
return spriteImage;
}
catch (ArgumentOutOfRangeException)
{
// ignored
}
}
catch (Exception e)
using (var mask = new Image<Bgra32>(rect.Width, rect.Height, SixLabors.ImageSharp.Color.Black))
{
Logger.Warning($"{m_Sprite.m_Name} Unable to render the packed sprite correctly.\n{e}");
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;
}
}
//Rectangle
spriteImage.Mutate(x => x.Flip(FlipMode.Vertical));
return spriteImage;
catch (Exception e)
{
Logger.Warning($"{m_Sprite.m_Name} Unable to render the packed sprite correctly.\n{e}");
}
}
return null;
//Rectangle
spriteImage.Mutate(x => x.Flip(FlipMode.Vertical));
return spriteImage;
}
private static Vector2[][] GetTriangles(SpriteRenderData m_RD)
+10 -11
View File
@@ -8,23 +8,24 @@ namespace AssetStudio
{
public static class Texture2DExtensions
{
public static Image<Bgra32> ConvertToImage(this Texture2D m_Texture2D, bool flip)
public static bool TryConvertToImage(this Texture2D m_Texture2D, bool flip, out Image<Bgra32> image)
{
image = null;
var converter = new Texture2DConverter(m_Texture2D);
var buff = BigArrayPool<byte>.Shared.Rent(converter.OutputDataSize);
var spanBuff = buff.AsSpan(0, converter.OutputDataSize);
try
{
if (!converter.DecodeTexture2D(buff))
return null;
return false;
var image = Image.LoadPixelData<Bgra32>(spanBuff, m_Texture2D.m_Width, m_Texture2D.m_Height);
image = Image.LoadPixelData<Bgra32>(spanBuff, m_Texture2D.m_Width, m_Texture2D.m_Height);
if (flip)
{
image.Mutate(x => x.Flip(FlipMode.Vertical));
}
return image;
return true;
}
finally
{
@@ -34,15 +35,13 @@ namespace AssetStudio
public static MemoryStream ConvertToStream(this Texture2D m_Texture2D, ImageFormat imageFormat, bool flip)
{
var image = ConvertToImage(m_Texture2D, flip);
if (image != null)
if (!TryConvertToImage(m_Texture2D, flip, out var image))
return null;
using (image)
{
using (image)
{
return image.ConvertToStream(imageFormat);
}
return image.ConvertToStream(imageFormat);
}
return null;
}
}
}