mirror of
https://github.com/aelurum/AssetStudio.git
synced 2025-05-27 22:00:23 -04:00
Improve Sprite export
This commit is contained in:
parent
351228e45c
commit
4ef160de34
@ -9,54 +9,61 @@ namespace Unity_Studio
|
|||||||
class Sprite
|
class Sprite
|
||||||
{
|
{
|
||||||
public string m_Name;
|
public string m_Name;
|
||||||
|
public RectangleF m_Rect;
|
||||||
|
public float m_PixelsToUnits;
|
||||||
|
public PointF m_Pivot;
|
||||||
|
public Guid first;
|
||||||
public PPtr texture;
|
public PPtr texture;
|
||||||
public PPtr m_SpriteAtlas;
|
public PPtr m_SpriteAtlas;
|
||||||
public RectangleF textureRect;
|
public RectangleF textureRect;
|
||||||
|
public PointF[][] m_PhysicsShape;
|
||||||
|
|
||||||
public Sprite(AssetPreloadData preloadData, bool readSwitch)
|
public Sprite(AssetPreloadData preloadData, bool readSwitch)
|
||||||
{
|
{
|
||||||
var sourceFile = preloadData.sourceFile;
|
var sourceFile = preloadData.sourceFile;
|
||||||
var a_Stream = preloadData.sourceFile.a_Stream;
|
var reader = preloadData.sourceFile.a_Stream;
|
||||||
a_Stream.Position = preloadData.Offset;
|
reader.Position = preloadData.Offset;
|
||||||
|
var version = sourceFile.version;
|
||||||
|
|
||||||
m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32());
|
m_Name = reader.ReadAlignedString(reader.ReadInt32());
|
||||||
if (readSwitch)
|
if (readSwitch)
|
||||||
{
|
{
|
||||||
//Rectf m_Rect
|
//Rectf m_Rect
|
||||||
var m_Rect = new RectangleF(a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle());
|
m_Rect = new RectangleF(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
|
||||||
//Vector2f m_Offset
|
//Vector2f m_Offset
|
||||||
a_Stream.Position += 8;
|
reader.Position += 8;
|
||||||
if (sourceFile.version[0] > 4 || (sourceFile.version[0] == 4 && sourceFile.version[1] >= 2)) //4.2 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 2)) //4.2 and up
|
||||||
{
|
{
|
||||||
//Vector4f m_Border
|
//Vector4f m_Border
|
||||||
a_Stream.Position += 16;
|
reader.Position += 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
var m_PixelsToUnits = a_Stream.ReadSingle();
|
m_PixelsToUnits = reader.ReadSingle();
|
||||||
if (sourceFile.version[0] > 5
|
if (version[0] > 5
|
||||||
|| (sourceFile.version[0] == 5 && sourceFile.version[1] > 4)
|
|| (version[0] == 5 && version[1] > 4)
|
||||||
|| (sourceFile.version[0] == 5 && sourceFile.version[1] == 4 && sourceFile.version[2] >= 2)) //5.4.2 and up
|
|| (version[0] == 5 && version[1] == 4 && version[2] >= 2)) //5.4.2 and up
|
||||||
{
|
{
|
||||||
//Vector2f m_Pivot
|
//Vector2f m_Pivot
|
||||||
a_Stream.Position += 8;
|
m_Pivot = new PointF(reader.ReadSingle(), reader.ReadSingle());
|
||||||
}
|
}
|
||||||
|
|
||||||
var m_Extrude = a_Stream.ReadUInt32();
|
var m_Extrude = reader.ReadUInt32();
|
||||||
if (sourceFile.version[0] > 5 || (sourceFile.version[0] == 5 && sourceFile.version[1] >= 3)) //5.3 and up TODO need more test
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 3)) //5.3 and up TODO need more test
|
||||||
{
|
{
|
||||||
var m_IsPolygon = a_Stream.ReadBoolean();
|
var m_IsPolygon = reader.ReadBoolean();
|
||||||
a_Stream.AlignStream(4);
|
reader.AlignStream(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sourceFile.version[0] >= 2017) //2017 and up
|
if (version[0] >= 2017) //2017 and up
|
||||||
{
|
{
|
||||||
//pair m_RenderDataKey
|
//pair m_RenderDataKey
|
||||||
a_Stream.Position += 24;
|
first = new Guid(reader.ReadBytes(16));
|
||||||
|
var second = reader.ReadInt64();
|
||||||
//vector m_AtlasTags
|
//vector m_AtlasTags
|
||||||
var size = a_Stream.ReadInt32();
|
var size = reader.ReadInt32();
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
var data = a_Stream.ReadAlignedString(a_Stream.ReadInt32());
|
var data = reader.ReadAlignedString(reader.ReadInt32());
|
||||||
}
|
}
|
||||||
|
|
||||||
//PPtr<SpriteAtlas> m_SpriteAtlas
|
//PPtr<SpriteAtlas> m_SpriteAtlas
|
||||||
@ -67,66 +74,92 @@ namespace Unity_Studio
|
|||||||
// PPtr<Texture2D> texture
|
// PPtr<Texture2D> texture
|
||||||
texture = sourceFile.ReadPPtr();
|
texture = sourceFile.ReadPPtr();
|
||||||
// PPtr<Texture2D> alphaTexture
|
// PPtr<Texture2D> alphaTexture
|
||||||
if (sourceFile.version[0] >= 5) //5.0 and up
|
if (version[0] >= 5) //5.0 and up
|
||||||
{
|
{
|
||||||
var alphaTexture = sourceFile.ReadPPtr();
|
var alphaTexture = sourceFile.ReadPPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sourceFile.version[0] > 5 || (sourceFile.version[0] == 5 && sourceFile.version[1] >= 6)) //5.6 and up
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
|
||||||
{
|
{
|
||||||
// vector m_SubMeshes
|
// vector m_SubMeshes
|
||||||
var size = a_Stream.ReadInt32();
|
var size = reader.ReadInt32();
|
||||||
// SubMesh data
|
// SubMesh data
|
||||||
if (sourceFile.version[0] > 2017 || (sourceFile.version[0] == 2017 && sourceFile.version[1] >= 3)) //2017.3 and up
|
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3)) //2017.3 and up
|
||||||
{
|
{
|
||||||
a_Stream.Position += 48 * size;
|
reader.Position += 48 * size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
a_Stream.Position += 44 * size;
|
reader.Position += 44 * size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// vector m_IndexBuffer
|
// vector m_IndexBuffer
|
||||||
size = a_Stream.ReadInt32();
|
size = reader.ReadInt32();
|
||||||
a_Stream.Position += size; //UInt8 data
|
reader.Position += size; //UInt8 data
|
||||||
a_Stream.AlignStream(4);
|
reader.AlignStream(4);
|
||||||
// VertexData m_VertexData
|
// VertexData m_VertexData
|
||||||
var m_CurrentChannels = a_Stream.ReadInt32();
|
var m_CurrentChannels = reader.ReadInt32();
|
||||||
var m_VertexCount = a_Stream.ReadUInt32();
|
var m_VertexCount = reader.ReadUInt32();
|
||||||
// vector m_Channels
|
// vector m_Channels
|
||||||
size = a_Stream.ReadInt32();
|
size = reader.ReadInt32();
|
||||||
a_Stream.Position += size * 4; //ChannelInfo data
|
reader.Position += size * 4; //ChannelInfo data
|
||||||
// TypelessData m_DataSize
|
// TypelessData m_DataSize
|
||||||
size = a_Stream.ReadInt32();
|
size = reader.ReadInt32();
|
||||||
a_Stream.Position += size; //UInt8 data
|
reader.Position += size; //UInt8 data
|
||||||
a_Stream.AlignStream(4);
|
reader.AlignStream(4);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// vector vertices
|
// vector vertices
|
||||||
var size = a_Stream.ReadInt32();
|
var size = reader.ReadInt32();
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
//SpriteVertex data
|
//SpriteVertex data
|
||||||
a_Stream.Position += 12; //Vector3f pos
|
reader.Position += 12; //Vector3f pos
|
||||||
if (sourceFile.version[0] < 4 || (sourceFile.version[0] == 4 && sourceFile.version[1] <= 1)) //4.1 and down
|
if (version[0] < 4 || (version[0] == 4 && version[1] <= 1)) //4.1 and down
|
||||||
a_Stream.Position += 8; //Vector2f uv
|
reader.Position += 8; //Vector2f uv
|
||||||
}
|
}
|
||||||
|
|
||||||
// vector indices
|
// vector indices
|
||||||
size = a_Stream.ReadInt32();
|
size = reader.ReadInt32();
|
||||||
a_Stream.Position += 2 * size; //UInt16 data
|
reader.Position += 2 * size; //UInt16 data
|
||||||
a_Stream.AlignStream(4);
|
reader.AlignStream(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rectf textureRect
|
// Rectf textureRect
|
||||||
textureRect = new RectangleF(a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle());
|
textureRect = new RectangleF(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
|
||||||
// Vector2f textureRectOffset
|
// Vector2f textureRectOffset
|
||||||
|
reader.Position += 8;
|
||||||
// Vector2f atlasRectOffset - 5.6 and up
|
// Vector2f atlasRectOffset - 5.6 and up
|
||||||
|
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
|
||||||
|
{
|
||||||
|
reader.Position += 8;
|
||||||
|
}
|
||||||
// unsigned int settingsRaw
|
// unsigned int settingsRaw
|
||||||
|
reader.Position += 4;
|
||||||
// Vector4f uvTransform - 4.2 and up
|
// Vector4f uvTransform - 4.2 and up
|
||||||
// float downscaleMultiplier - 2017 and up
|
if (version[0] > 4 || (version[0] == 4 && version[1] >= 2)) //4.2 and up
|
||||||
//vector m_PhysicsShape - 2017 and up
|
{
|
||||||
|
reader.Position += 16;
|
||||||
|
}
|
||||||
|
if (version[0] >= 2017) //2017 and up
|
||||||
|
{
|
||||||
|
// float downscaleMultiplier - 2017 and up
|
||||||
|
reader.Position += 4;
|
||||||
|
//vector m_PhysicsShape - 2017 and up
|
||||||
|
var m_PhysicsShape_size = reader.ReadInt32();
|
||||||
|
m_PhysicsShape = new PointF[m_PhysicsShape_size][];
|
||||||
|
for (int i = 0; i < m_PhysicsShape_size; i++)
|
||||||
|
{
|
||||||
|
var data_size = reader.ReadInt32();
|
||||||
|
//Vector2f
|
||||||
|
m_PhysicsShape[i] = new PointF[data_size];
|
||||||
|
for (int j = 0; j < data_size; j++)
|
||||||
|
{
|
||||||
|
m_PhysicsShape[i][j] = new PointF(reader.ReadSingle(), reader.ReadSingle());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -8,55 +8,56 @@ namespace Unity_Studio
|
|||||||
{
|
{
|
||||||
class SpriteAtlas
|
class SpriteAtlas
|
||||||
{
|
{
|
||||||
public List<PPtr> m_PackedSprites = new List<PPtr>();
|
|
||||||
public List<PPtr> textures = new List<PPtr>();
|
public List<PPtr> textures = new List<PPtr>();
|
||||||
public List<RectangleF> textureRects = new List<RectangleF>();
|
public List<RectangleF> textureRects = new List<RectangleF>();
|
||||||
|
public List<Guid> guids = new List<Guid>();
|
||||||
|
|
||||||
|
|
||||||
public SpriteAtlas(AssetPreloadData preloadData)
|
public SpriteAtlas(AssetPreloadData preloadData)
|
||||||
{
|
{
|
||||||
var sourceFile = preloadData.sourceFile;
|
var sourceFile = preloadData.sourceFile;
|
||||||
var a_Stream = preloadData.sourceFile.a_Stream;
|
var reader = preloadData.sourceFile.a_Stream;
|
||||||
a_Stream.Position = preloadData.Offset;
|
reader.Position = preloadData.Offset;
|
||||||
|
|
||||||
var m_Name = a_Stream.ReadAlignedString(a_Stream.ReadInt32());
|
var m_Name = reader.ReadAlignedString(reader.ReadInt32());
|
||||||
//vector m_PackedSprites
|
//vector m_PackedSprites
|
||||||
var size = a_Stream.ReadInt32();
|
var size = reader.ReadInt32();
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
//PPtr<Sprite> data
|
//PPtr<Sprite> data
|
||||||
m_PackedSprites.Add(sourceFile.ReadPPtr());
|
sourceFile.ReadPPtr();
|
||||||
}
|
}
|
||||||
//vector m_PackedSpriteNamesToIndex
|
//vector m_PackedSpriteNamesToIndex
|
||||||
size = a_Stream.ReadInt32();
|
size = reader.ReadInt32();
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
var data = a_Stream.ReadAlignedString(a_Stream.ReadInt32());
|
var data = reader.ReadAlignedString(reader.ReadInt32());
|
||||||
}
|
}
|
||||||
//map m_RenderDataMap
|
//map m_RenderDataMap
|
||||||
size = a_Stream.ReadInt32();
|
size = reader.ReadInt32();
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
//pair first
|
//pair first
|
||||||
a_Stream.Position += 24;
|
guids.Add(new Guid(reader.ReadBytes(16)));
|
||||||
|
var second = reader.ReadInt64();
|
||||||
//SpriteAtlasData second
|
//SpriteAtlasData second
|
||||||
// PPtr<Texture2D> texture
|
// PPtr<Texture2D> texture
|
||||||
textures.Add(sourceFile.ReadPPtr());
|
textures.Add(sourceFile.ReadPPtr());
|
||||||
// PPtr<Texture2D> alphaTexture
|
// PPtr<Texture2D> alphaTexture
|
||||||
var alphaTexture = sourceFile.ReadPPtr();
|
var alphaTexture = sourceFile.ReadPPtr();
|
||||||
// Rectf textureRect
|
// Rectf textureRect
|
||||||
textureRects.Add(new RectangleF(a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle(), a_Stream.ReadSingle()));
|
textureRects.Add(new RectangleF(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()));
|
||||||
// Vector2f textureRectOffset
|
// Vector2f textureRectOffset
|
||||||
a_Stream.Position += 8;
|
reader.Position += 8;
|
||||||
if (sourceFile.version[0] > 2017 || (sourceFile.version[0] == 2017 && sourceFile.version[1] >= 2))//2017.2 and up
|
if (sourceFile.version[0] > 2017 || (sourceFile.version[0] == 2017 && sourceFile.version[1] >= 2))//2017.2 and up
|
||||||
{
|
{
|
||||||
// Vector2f atlasRectOffset
|
// Vector2f atlasRectOffset
|
||||||
a_Stream.Position += 8;
|
reader.Position += 8;
|
||||||
}
|
}
|
||||||
// Vector4f uvTransform
|
// Vector4f uvTransform
|
||||||
// float downscaleMultiplier
|
// float downscaleMultiplier
|
||||||
// unsigned int settingsRaw
|
// unsigned int settingsRaw
|
||||||
a_Stream.Position += 24;
|
reader.Position += 24;
|
||||||
}
|
}
|
||||||
//string m_Tag
|
//string m_Tag
|
||||||
//bool m_IsVariant
|
//bool m_IsVariant
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@ -1909,28 +1910,18 @@ namespace Unity_Studio
|
|||||||
return selectFile.Distinct().ToArray();
|
return selectFile.Distinct().ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO Tight方式的Sprite需要读取多边形信息进行绘图
|
|
||||||
public static Bitmap GetImageFromSprite(AssetPreloadData asset)
|
public static Bitmap GetImageFromSprite(AssetPreloadData asset)
|
||||||
{
|
{
|
||||||
if (spriteCache.TryGetValue(asset, out var bitmap))
|
if (spriteCache.TryGetValue(asset, out var bitmap))
|
||||||
return (Bitmap)bitmap.Clone();
|
return (Bitmap)bitmap.Clone();
|
||||||
var m_Sprite = new Sprite(asset, true);
|
var m_Sprite = new Sprite(asset, true);
|
||||||
if (m_Sprite.m_SpriteAtlas != null && assetsfileList.TryGetPD(m_Sprite.m_SpriteAtlas, out var assetPreloadData))
|
if (assetsfileList.TryGetPD(m_Sprite.m_SpriteAtlas, out var assetPreloadData))
|
||||||
{
|
{
|
||||||
var m_SpriteAtlas = new SpriteAtlas(assetPreloadData);
|
var m_SpriteAtlas = new SpriteAtlas(assetPreloadData);
|
||||||
bool find = false;
|
var index = m_SpriteAtlas.guids.FindIndex(x => x == m_Sprite.first);
|
||||||
int index = 0;
|
if (index >= 0 && assetsfileList.TryGetPD(m_SpriteAtlas.textures[index], out assetPreloadData))
|
||||||
for (; index < m_SpriteAtlas.m_PackedSprites.Count; index++)
|
|
||||||
{
|
{
|
||||||
if (assetsfileList.TryGetPD(m_SpriteAtlas.m_PackedSprites[index], out assetPreloadData) && assetPreloadData == asset)
|
return CutImage(asset, assetPreloadData, m_SpriteAtlas.textureRects[index], m_Sprite);
|
||||||
{
|
|
||||||
find = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (find && assetsfileList.TryGetPD(m_SpriteAtlas.textures[index], out assetPreloadData))
|
|
||||||
{
|
|
||||||
return CutImage(asset, assetPreloadData, m_SpriteAtlas.textureRects[index]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1964,5 +1955,45 @@ namespace Unity_Studio
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Bitmap CutImage(AssetPreloadData asset, AssetPreloadData texture2DAsset, RectangleF textureRect, Sprite sprite)
|
||||||
|
{
|
||||||
|
var texture2D = new Texture2D(texture2DAsset, true);
|
||||||
|
using (var originalImage = texture2D.ConvertToBitmap(false))
|
||||||
|
{
|
||||||
|
if (originalImage != null)
|
||||||
|
{
|
||||||
|
var info = texture2DAsset.InfoText;
|
||||||
|
var start = info.IndexOf("Format");
|
||||||
|
info = info.Substring(start, info.Length - start);
|
||||||
|
asset.InfoText = $"Width: {textureRect.Width}\nHeight: {textureRect.Height}\n" + info;
|
||||||
|
var spriteImage = originalImage.Clone(textureRect, PixelFormat.Format32bppArgb);
|
||||||
|
using (var brush = new TextureBrush(spriteImage))
|
||||||
|
{
|
||||||
|
using (var path = new GraphicsPath())
|
||||||
|
{
|
||||||
|
foreach (var p in sprite.m_PhysicsShape)
|
||||||
|
path.AddPolygon(p);
|
||||||
|
using (var matr = new Matrix())
|
||||||
|
{
|
||||||
|
matr.Translate(sprite.m_Rect.Width * sprite.m_Pivot.X, sprite.m_Rect.Height * sprite.m_Pivot.Y);
|
||||||
|
matr.Scale(sprite.m_PixelsToUnits, sprite.m_PixelsToUnits);
|
||||||
|
path.Flatten(matr);
|
||||||
|
var bitmap = new Bitmap((int)textureRect.Width, (int)textureRect.Height);
|
||||||
|
using (var graphic = Graphics.FromImage(bitmap))
|
||||||
|
{
|
||||||
|
graphic.FillPath(brush, path);
|
||||||
|
bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
|
||||||
|
spriteCache.Add(asset, bitmap);
|
||||||
|
return (Bitmap)bitmap.Clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user