Skip to content

Commit 8155642

Browse files
Fix FlattenFrame issue (#23)
* Renamed "Solution Items" solution directory to ".root" * Added root solution items to .root solution directory. * Extension class file should use `.Extension` in the name * Added `Deconstruct` method for `Rgba32` * Ignore CA1823 warning in AsepriteFIleLoader.Constants. * Add xml doc for `AsepriteFileLoader` * Simplify `PixelsToColor` method * Add Directory.Build.props for benchmarks and build directories.# * Added examples * Default values for flatten frame params * Include documentation for all parameters * Resolve issue where cel witdth was being used instead of frame width * Renamed AsepriteColor.Extensions to Rgba32.Extensions These methods were always Rgba32 extension and should have been named appropriately that. Added method for converting an array of `ReadOnlySpan<Rgba32>` * Added license header * Removed unused using * Added MonoGame Example * Bump to Version 1.1.0 There was a patch change that fixed a bug, but additional functionality was added to the Rgba32 extension methods, so minor version increase was justified.
1 parent a2b1234 commit 8155642

27 files changed

+574
-107
lines changed

AsepriteDotNet.sln

+47-1
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,26 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{5F219449
1717
EndProject
1818
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AsepriteDotNet.Tests", "tests\AsepriteDotNet.Tests\AsepriteDotNet.Tests.csproj", "{A289C75E-0BCF-421F-AAE0-050F45AC4F4E}"
1919
EndProject
20-
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{2B0F6763-3C96-4753-8E12-6A2975369212}"
20+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".root", ".root", "{2B0F6763-3C96-4753-8E12-6A2975369212}"
2121
ProjectSection(SolutionItems) = preProject
22+
.editorconfig = .editorconfig
23+
.gitignore = .gitignore
2224
Directory.Build.props = Directory.Build.props
25+
LICENSE = LICENSE
26+
README.md = README.md
2327
EndProjectSection
2428
EndProject
2529
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", "{C4B76AC7-83D0-4F29-BAB9-3C0EAFB31C0D}"
30+
ProjectSection(SolutionItems) = preProject
31+
benchmarks\Directory.Build.props = benchmarks\Directory.Build.props
32+
EndProjectSection
2633
EndProject
2734
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ColorProcessingBenchmark", "benchmarks\ColorProcessingBenchmark\ColorProcessingBenchmark.csproj", "{201F4F7E-C68D-400C-AB87-9A77578DDBEB}"
2835
EndProject
2936
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{1515BA5C-6095-4F5F-94E6-7D54D09321DE}"
37+
ProjectSection(SolutionItems) = preProject
38+
build\Directory.Build.props = build\Directory.Build.props
39+
EndProjectSection
3040
EndProject
3141
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AsepriteDotNet.Build", "build\AsepriteDotNet.Build.csproj", "{27B2E61B-9CA4-44D2-834F-772B7D233D9F}"
3242
EndProject
@@ -35,6 +45,19 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{
3545
.github\workflows\main.yml = .github\workflows\main.yml
3646
EndProjectSection
3747
EndProject
48+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{E55B2B0D-9615-434F-942A-6C496A02E617}"
49+
ProjectSection(SolutionItems) = preProject
50+
examples\Directory.Build.props = examples\Directory.Build.props
51+
EndProjectSection
52+
EndProject
53+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FlattenFrameExample", "examples\FlattenFrameExample\FlattenFrameExample.csproj", "{A6243E15-9D53-4FAB-A2B5-F216614AF832}"
54+
EndProject
55+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LoadFileExample", "examples\LoadFileExample\LoadFileExample.csproj", "{E43B057B-37B4-4C77-AC25-376380318AEF}"
56+
EndProject
57+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProcessorExample", "examples\ProcessorExample\ProcessorExample.csproj", "{DAD91498-F650-44C7-AAB8-A3454E084E5D}"
58+
EndProject
59+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonoGameExample", "examples\MonoGameExample\MonoGameExample.csproj", "{6FA09867-535B-4200-9D0A-88A2987BF033}"
60+
EndProject
3861
Global
3962
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4063
Debug|Any CPU = Debug|Any CPU
@@ -57,6 +80,22 @@ Global
5780
{27B2E61B-9CA4-44D2-834F-772B7D233D9F}.Debug|Any CPU.Build.0 = Debug|Any CPU
5881
{27B2E61B-9CA4-44D2-834F-772B7D233D9F}.Release|Any CPU.ActiveCfg = Release|Any CPU
5982
{27B2E61B-9CA4-44D2-834F-772B7D233D9F}.Release|Any CPU.Build.0 = Release|Any CPU
83+
{A6243E15-9D53-4FAB-A2B5-F216614AF832}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
84+
{A6243E15-9D53-4FAB-A2B5-F216614AF832}.Debug|Any CPU.Build.0 = Debug|Any CPU
85+
{A6243E15-9D53-4FAB-A2B5-F216614AF832}.Release|Any CPU.ActiveCfg = Release|Any CPU
86+
{A6243E15-9D53-4FAB-A2B5-F216614AF832}.Release|Any CPU.Build.0 = Release|Any CPU
87+
{E43B057B-37B4-4C77-AC25-376380318AEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
88+
{E43B057B-37B4-4C77-AC25-376380318AEF}.Debug|Any CPU.Build.0 = Debug|Any CPU
89+
{E43B057B-37B4-4C77-AC25-376380318AEF}.Release|Any CPU.ActiveCfg = Release|Any CPU
90+
{E43B057B-37B4-4C77-AC25-376380318AEF}.Release|Any CPU.Build.0 = Release|Any CPU
91+
{DAD91498-F650-44C7-AAB8-A3454E084E5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
92+
{DAD91498-F650-44C7-AAB8-A3454E084E5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
93+
{DAD91498-F650-44C7-AAB8-A3454E084E5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
94+
{DAD91498-F650-44C7-AAB8-A3454E084E5D}.Release|Any CPU.Build.0 = Release|Any CPU
95+
{6FA09867-535B-4200-9D0A-88A2987BF033}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
96+
{6FA09867-535B-4200-9D0A-88A2987BF033}.Debug|Any CPU.Build.0 = Debug|Any CPU
97+
{6FA09867-535B-4200-9D0A-88A2987BF033}.Release|Any CPU.ActiveCfg = Release|Any CPU
98+
{6FA09867-535B-4200-9D0A-88A2987BF033}.Release|Any CPU.Build.0 = Release|Any CPU
6099
EndGlobalSection
61100
GlobalSection(SolutionProperties) = preSolution
62101
HideSolutionNode = FALSE
@@ -67,5 +106,12 @@ Global
67106
{201F4F7E-C68D-400C-AB87-9A77578DDBEB} = {C4B76AC7-83D0-4F29-BAB9-3C0EAFB31C0D}
68107
{27B2E61B-9CA4-44D2-834F-772B7D233D9F} = {1515BA5C-6095-4F5F-94E6-7D54D09321DE}
69108
{BC452291-6909-42FE-9343-7FD2F4F4F0E5} = {2B0F6763-3C96-4753-8E12-6A2975369212}
109+
{A6243E15-9D53-4FAB-A2B5-F216614AF832} = {E55B2B0D-9615-434F-942A-6C496A02E617}
110+
{E43B057B-37B4-4C77-AC25-376380318AEF} = {E55B2B0D-9615-434F-942A-6C496A02E617}
111+
{DAD91498-F650-44C7-AAB8-A3454E084E5D} = {E55B2B0D-9615-434F-942A-6C496A02E617}
112+
{6FA09867-535B-4200-9D0A-88A2987BF033} = {E55B2B0D-9615-434F-942A-6C496A02E617}
113+
EndGlobalSection
114+
GlobalSection(ExtensibilityGlobals) = postSolution
115+
SolutionGuid = {ABE689B5-F304-403F-A1E4-9973EB2F5FBD}
70116
EndGlobalSection
71117
EndGlobal

Directory.Build.props

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<NeutralLanguage>en</NeutralLanguage>
2121
<ImplicitUsings>enable</ImplicitUsings>
2222
<Nullable>enable</Nullable>
23-
<Version>1.0.0</Version>
23+
<Version>1.1.0</Version>
2424
</PropertyGroup>
2525

2626
<!-- Setup Code Analysis using the .editorconfig file -->

benchmarks/Directory.Build.props

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project>
3+
4+
<!-- Set the project category used by the root Directory.Build.props -->
5+
<PropertyGroup>
6+
<ProjectCategory>benchmarks</ProjectCategory>
7+
</PropertyGroup>
8+
9+
<!-- Import the root prop last -->
10+
<Import Project="$(MSBuildThisFileDirectory)..\Directory.Build.props" />
11+
</Project>

build/Directory.Build.props

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project>
3+
4+
<!-- Set the project category used by the root Directory.Build.props -->
5+
<PropertyGroup>
6+
<ProjectCategory>build</ProjectCategory>
7+
</PropertyGroup>
8+
9+
<!-- Import the root prop last -->
10+
<Import Project="$(MSBuildThisFileDirectory)..\Directory.Build.props" />
11+
</Project>

examples/Directory.Build.props

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project>
3+
4+
5+
<PropertyGroup>
6+
<OutputType>Exe</OutputType>
7+
<TargetFramework>net8.0</TargetFramework>
8+
<ProjectCategory>examples</ProjectCategory>
9+
<GenerateDocumentationFile>false</GenerateDocumentationFile>
10+
<IsPackable>false</IsPackable>
11+
<Copyright>Copyright © 2024 Christopher Whitley</Copyright>
12+
<Authors>Christopher Whitley and contributors</Authors>
13+
<Company>Aristurtle</Company>
14+
</PropertyGroup>
15+
16+
<ItemGroup>
17+
<None Include="../adventurer.aseprite" CopyToOutputDirectory="PreserveNewest" />
18+
</ItemGroup>
19+
20+
<ItemGroup>
21+
<ProjectReference Include="..\..\source\AsepriteDotNet\AsepriteDotNet.csproj" />
22+
</ItemGroup>
23+
24+
<Import Project="$(MSBuildThisFileDirectory)..\Directory.Build.props" />
25+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<Project Sdk="Microsoft.NET.Sdk"/>
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (c) Christopher Whitley. All rights reserved.
2+
// Licensed under the MIT license.
3+
// See LICENSE file in the project root for full license information.
4+
5+
using AsepriteDotNet.Aseprite;
6+
using AsepriteDotNet.Aseprite.Types;
7+
using AsepriteDotNet.Common;
8+
using AsepriteDotNet.IO;
9+
10+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11+
///
12+
/// Load the file using the AsepriteFileLoader. In this example, we are passing the path to the file. There is also
13+
/// an overload where you can pass a stream instead if you needed.
14+
///
15+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16+
AsepriteFile aseFile = AsepriteFileLoader.FromFile("adventurer.aseprite");
17+
18+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19+
///
20+
/// Flatten a single frame to get the pixel representation of that frame.
21+
///
22+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
23+
Rgba32[] frame0Pixels = aseFile.Frames[0].FlattenFrame(onlyVisibleLayers: true, includeBackgroundLayer: false, includeTilemapCels: true);
24+
25+
26+
// At this point you can use the pixel data of that frame in your application ever how you need it.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<Project Sdk="Microsoft.NET.Sdk"/>

examples/LoadFileExample/Program.cs

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright (c) Christopher Whitley. All rights reserved.
2+
// Licensed under the MIT license.
3+
// See LICENSE file in the project root for full license information.
4+
5+
using AsepriteDotNet.Aseprite;
6+
using AsepriteDotNet.IO;
7+
8+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
9+
///
10+
/// Load the file using the AsepriteFileLoader. In this example, we are passing the path to the file. There is also
11+
/// an overload where you can pass a stream instead if you needed.
12+
///
13+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
14+
AsepriteFile aseFile = AsepriteFileLoader.FromFile("adventurer.aseprite");
15+
16+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
17+
///
18+
/// Output information about the file read.
19+
///
20+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
21+
string info =
22+
$"""
23+
Filename: {aseFile.Name}
24+
Color Depth: {aseFile.ColorDepth}
25+
Palette Size: {aseFile.Palette.Count}
26+
Canvas Size: {aseFile.CanvasWidth} x {aseFile.CanvasHeight}
27+
Frame Count: {aseFile.Frames.Length}
28+
Layers Count: {aseFile.Layers.Length}
29+
Slices Count: {aseFile.Slices.Length}
30+
Tags Count: {aseFile.Tags.Length}
31+
Tileset Count: {aseFile.Tilesets.Length}
32+
""";
33+
34+
Console.WriteLine(info);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"version": 1,
3+
"isRoot": true,
4+
"tools": {
5+
"dotnet-mgcb": {
6+
"version": "3.8.1.303",
7+
"commands": [
8+
"mgcb"
9+
]
10+
},
11+
"dotnet-mgcb-editor": {
12+
"version": "3.8.1.303",
13+
"commands": [
14+
"mgcb-editor"
15+
]
16+
},
17+
"dotnet-mgcb-editor-linux": {
18+
"version": "3.8.1.303",
19+
"commands": [
20+
"mgcb-editor-linux"
21+
]
22+
},
23+
"dotnet-mgcb-editor-windows": {
24+
"version": "3.8.1.303",
25+
"commands": [
26+
"mgcb-editor-windows"
27+
]
28+
},
29+
"dotnet-mgcb-editor-mac": {
30+
"version": "3.8.1.303",
31+
"commands": [
32+
"mgcb-editor-mac"
33+
]
34+
}
35+
}
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
#----------------------------- Global Properties ----------------------------#
3+
4+
/outputDir:bin/$(Platform)
5+
/intermediateDir:obj/$(Platform)
6+
/platform:DesktopGL
7+
/config:
8+
/profile:Reach
9+
/compress:False
10+
11+
#-------------------------------- References --------------------------------#
12+
13+
14+
#---------------------------------- Content ---------------------------------#
15+

examples/MonoGameExample/Game1.cs

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Copyright (c) Christopher Whitley. All rights reserved.
2+
// Licensed under the MIT license.
3+
// See LICENSE file in the project root for full license information.
4+
5+
using AsepriteDotNet.Aseprite;
6+
using AsepriteDotNet.Aseprite.Types;
7+
using AsepriteDotNet.Common;
8+
using AsepriteDotNet.IO;
9+
using Microsoft.Xna.Framework;
10+
using Microsoft.Xna.Framework.Graphics;
11+
12+
namespace MonoGameExample;
13+
14+
public class Game1 : Game
15+
{
16+
private GraphicsDeviceManager _graphics;
17+
private SpriteBatch _spriteBatch;
18+
private Texture2D _texture;
19+
20+
public Game1()
21+
{
22+
_graphics = new GraphicsDeviceManager(this);
23+
Content.RootDirectory = "Content";
24+
IsMouseVisible = true;
25+
}
26+
27+
protected override void LoadContent()
28+
{
29+
_spriteBatch = new SpriteBatch(GraphicsDevice);
30+
31+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
32+
///
33+
/// Load the file. In this example, we're not using the MGCB/Content Pipeline and have the Aseprite file set as
34+
/// a file in our project that is copied the output directory. Because of this, we can use the
35+
/// TitleContainer.OpenStream to get a stream to the file and use that to load it.
36+
///
37+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
38+
AsepriteFile aseFile;
39+
using (Stream stream = TitleContainer.OpenStream("adventurer.aseprite"))
40+
{
41+
aseFile = AsepriteFileLoader.FromStream("adventurer", stream);
42+
}
43+
44+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
45+
///
46+
/// Flatten a frame so that we can get the full color data of that frame.
47+
///
48+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
49+
Rgba32[] frame0Pixels = aseFile.Frames[0].FlattenFrame();
50+
51+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
52+
///
53+
/// AsepriteDotNet internally uses it's own Rgba32 color struct to represent color data. This needs to be
54+
/// converted to the Microsoft.Xna.Framework.Color value type used by MonoGame. AsepriteDotNet offers
55+
/// extension methods on Rgba32 for converting it to a different color type.
56+
///
57+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
58+
Color[] pixels = frame0Pixels.As<Color>(rgba => new Color(rgba.PackedValue));
59+
60+
61+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
62+
///
63+
/// Create the texture now that we have all the data we need
64+
///
65+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
66+
_texture = new Texture2D(GraphicsDevice, aseFile.Frames[0].Size.Width, aseFile.Frames[0].Size.Height);
67+
_texture.SetData<Color>(pixels);
68+
}
69+
70+
protected override void Draw(GameTime gameTime)
71+
{
72+
GraphicsDevice.Clear(Color.CornflowerBlue);
73+
74+
_spriteBatch.Begin(samplerState: SamplerState.PointClamp);
75+
_spriteBatch.Draw(_texture, new Vector2(100, 100), null, Color.White, 0.0f, Vector2.Zero, 5.0f, SpriteEffects.None, 0.0f);
76+
_spriteBatch.End();
77+
78+
79+
base.Draw(gameTime);
80+
}
81+
}

examples/MonoGameExample/Icon.bmp

256 KB
Binary file not shown.

examples/MonoGameExample/Icon.ico

144 KB
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>WinExe</OutputType>
4+
<RollForward>Major</RollForward>
5+
<PublishReadyToRun>false</PublishReadyToRun>
6+
<TieredCompilation>false</TieredCompilation>
7+
<Nullable>disable</Nullable>
8+
</PropertyGroup>
9+
<PropertyGroup>
10+
<ApplicationManifest>app.manifest</ApplicationManifest>
11+
<ApplicationIcon>Icon.ico</ApplicationIcon>
12+
</PropertyGroup>
13+
<ItemGroup>
14+
<None Remove="Icon.ico" />
15+
<None Remove="Icon.bmp" />
16+
</ItemGroup>
17+
<ItemGroup>
18+
<EmbeddedResource Include="Icon.ico" />
19+
<EmbeddedResource Include="Icon.bmp" />
20+
</ItemGroup>
21+
<ItemGroup>
22+
<PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.1.303" />
23+
<PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.1.303" />
24+
</ItemGroup>
25+
<Target Name="RestoreDotnetTools" BeforeTargets="Restore">
26+
<Message Text="Restoring dotnet tools" Importance="High" />
27+
<Exec Command="dotnet tool restore" />
28+
</Target>
29+
</Project>

examples/MonoGameExample/Program.cs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Copyright (c) Christopher Whitley. All rights reserved.
2+
// Licensed under the MIT license.
3+
// See LICENSE file in the project root for full license information.
4+
5+
using var game = new MonoGameExample.Game1();
6+
game.Run();

0 commit comments

Comments
 (0)