mirror of
https://github.com/aelurum/AssetStudio.git
synced 2026-11-14 11:18:47 -05:00
Some refactor for Texture2DExtensions
This commit is contained in:
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user