Skip to content

Commit 17263c9

Browse files
Merge branch 'feature/gui'
2 parents fe767f3 + cf98ddb commit 17263c9

29 files changed

+1574
-165
lines changed

ArcanumTextureSlicer/ArcanumTextureSlicer/ArcanumTextureSlicer.csproj renamed to ArcanumTextureSlicer/ArcanumTextureSlicer.Console/ArcanumTextureSlicer.Console.csproj

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
<ProjectGuid>{8D83F596-37CF-4683-BA03-51596B348A40}</ProjectGuid>
88
<OutputType>Exe</OutputType>
99
<AppDesignerFolder>Properties</AppDesignerFolder>
10-
<RootNamespace>ArcanumTextureSlicer</RootNamespace>
11-
<AssemblyName>ArcanumTextureSlicer</AssemblyName>
10+
<RootNamespace>ArcanumTextureSlicer.Console</RootNamespace>
11+
<AssemblyName>ArcanumTextureSlicer.Console</AssemblyName>
1212
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
1313
<FileAlignment>512</FileAlignment>
1414
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
@@ -45,7 +45,6 @@
4545
<Reference Include="System.Xml" />
4646
</ItemGroup>
4747
<ItemGroup>
48-
<Compile Include="BitmapExtensions.cs" />
4948
<Compile Include="Program.cs" />
5049
<Compile Include="Properties\AssemblyInfo.cs" />
5150
</ItemGroup>
@@ -55,7 +54,11 @@
5554
</None>
5655
</ItemGroup>
5756
<ItemGroup>
58-
<EmbeddedResource Include="Resources\SampleTile.png" />
57+
<ProjectReference Include="..\ArcanumTextureSlicer.Core\ArcanumTextureSlicer.Core.csproj">
58+
<Project>{ecc9c8a1-77c5-4f4e-9e16-6d9f8d2fd8ca}</Project>
59+
<Name>ArcanumTextureSlicer.Core</Name>
60+
<EmbedInteropTypes>False</EmbedInteropTypes>
61+
</ProjectReference>
5962
</ItemGroup>
6063
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
6164
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
using System;
2+
using System.Drawing;
3+
using System.Drawing.Imaging;
4+
using System.IO;
5+
using System.Linq;
6+
using ArcanumTextureSlicer.Core;
7+
8+
namespace ArcanumTextureSlicer.Console
9+
{
10+
public class Program
11+
{
12+
public static void Main(string[] args)
13+
{
14+
if (args == null || args.Length < 2)
15+
{
16+
System.Console.WriteLine($"Not enough arguments.");
17+
return;
18+
}
19+
20+
var inputFile = args[0];
21+
var outputFolder = args[1];
22+
23+
if (Directory.Exists(outputFolder))
24+
{
25+
Directory.GetFiles(outputFolder, "tile_???_???.bmp").ToList().ForEach(File.Delete);
26+
}
27+
else
28+
{
29+
Directory.CreateDirectory(outputFolder);
30+
}
31+
32+
try
33+
{
34+
using (var inputBitmap = new Bitmap(inputFile))
35+
{
36+
var initTileCenter = inputBitmap.GetStartTileCenter();
37+
var initTileX = args.Length > 2 ? int.Parse(args[2]) : initTileCenter.X;
38+
var initTileY = args.Length > 3 ? int.Parse(args[3]) : initTileCenter.Y;
39+
40+
foreach (var tile in inputBitmap.ToTiles(initTileX, initTileY))
41+
{
42+
if (tile.Row == 0 && tile.Column == 0 &&
43+
initTileCenter.X == initTileX &&
44+
initTileCenter.Y == initTileY)
45+
{
46+
// Do not export start tile
47+
continue;
48+
}
49+
using (var outputBitmap = inputBitmap.CreateTile(tile.X, tile.Y))
50+
{
51+
if (outputBitmap.IsTransparent())
52+
{
53+
System.Console.WriteLine($"Transparent tile at {tile.Row},{tile.Column}");
54+
}
55+
else
56+
{
57+
try
58+
{
59+
var tilePath =
60+
$"{outputFolder.TrimEnd('/', '\\')}\\tile_{tile.Row.ToString("D3")}_{tile.Column.ToString("D3")}.bmp";
61+
System.Console.WriteLine(tilePath);
62+
outputBitmap.Save(tilePath, ImageFormat.Bmp);
63+
}
64+
catch (Exception e)
65+
{
66+
System.Console.WriteLine(e);
67+
}
68+
}
69+
}
70+
}
71+
}
72+
}
73+
catch (FileNotFoundException e)
74+
{
75+
System.Console.WriteLine(e);
76+
}
77+
}
78+
}
79+
}

ArcanumTextureSlicer/ArcanumTextureSlicer/Properties/AssemblyInfo.cs renamed to ArcanumTextureSlicer/ArcanumTextureSlicer.Console/Properties/AssemblyInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// General Information about an assembly is controlled through the following
66
// set of attributes. Change these attribute values to modify the information
77
// associated with an assembly.
8-
[assembly: AssemblyTitle("ArcanumTextureSlicer")]
8+
[assembly: AssemblyTitle("ArcanumTextureSlicer.Console")]
99
[assembly: AssemblyDescription("")]
1010
[assembly: AssemblyConfiguration("")]
1111
[assembly: AssemblyCompany("")]
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<ProjectGuid>{ECC9C8A1-77C5-4F4E-9E16-6D9F8D2FD8CA}</ProjectGuid>
8+
<OutputType>Library</OutputType>
9+
<AppDesignerFolder>Properties</AppDesignerFolder>
10+
<RootNamespace>ArcanumTextureSlicer.Core</RootNamespace>
11+
<AssemblyName>ArcanumTextureSlicer.Core</AssemblyName>
12+
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
13+
<FileAlignment>512</FileAlignment>
14+
<TargetFrameworkProfile />
15+
</PropertyGroup>
16+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
17+
<DebugSymbols>true</DebugSymbols>
18+
<DebugType>full</DebugType>
19+
<Optimize>false</Optimize>
20+
<OutputPath>bin\Debug\</OutputPath>
21+
<DefineConstants>DEBUG;TRACE</DefineConstants>
22+
<ErrorReport>prompt</ErrorReport>
23+
<WarningLevel>4</WarningLevel>
24+
</PropertyGroup>
25+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
26+
<DebugType>pdbonly</DebugType>
27+
<Optimize>true</Optimize>
28+
<OutputPath>bin\Release\</OutputPath>
29+
<DefineConstants>TRACE</DefineConstants>
30+
<ErrorReport>prompt</ErrorReport>
31+
<WarningLevel>4</WarningLevel>
32+
</PropertyGroup>
33+
<ItemGroup>
34+
<Reference Include="System" />
35+
<Reference Include="System.Core" />
36+
<Reference Include="System.Drawing" />
37+
<Reference Include="System.Xml.Linq" />
38+
<Reference Include="System.Data.DataSetExtensions" />
39+
<Reference Include="Microsoft.CSharp" />
40+
<Reference Include="System.Data" />
41+
<Reference Include="System.Net.Http" />
42+
<Reference Include="System.Xml" />
43+
</ItemGroup>
44+
<ItemGroup>
45+
<Compile Include="BitmapExtensions.cs" />
46+
<Compile Include="Properties\AssemblyInfo.cs" />
47+
<Compile Include="Tile.cs" />
48+
</ItemGroup>
49+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
50+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
51+
Other similar extension points exist, see Microsoft.Common.targets.
52+
<Target Name="BeforeBuild">
53+
</Target>
54+
<Target Name="AfterBuild">
55+
</Target>
56+
-->
57+
</Project>

ArcanumTextureSlicer/ArcanumTextureSlicer/BitmapExtensions.cs renamed to ArcanumTextureSlicer/ArcanumTextureSlicer.Core/BitmapExtensions.cs

Lines changed: 48 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,14 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Drawing;
34
using System.Drawing.Imaging;
4-
using System.Reflection;
5+
using System.Linq;
56
using System.Runtime.InteropServices;
67

7-
namespace ArcanumTextureSlicer
8+
namespace ArcanumTextureSlicer.Core
89
{
910
public static class BitmapExtensions
1011
{
11-
public const int TileWidth = 78;
12-
public const int HalfTileWidth = 39;
13-
public const int TileHeight = 40;
14-
public const int HalfTileHeight = 20;
15-
public const int TileXSpace = 2;
16-
public const int HalfTileXSpace = 1;
17-
private static Bitmap _sampleTile;
18-
19-
public static Bitmap SampleTile =>
20-
_sampleTile ??
21-
(_sampleTile = new Bitmap(Assembly.GetExecutingAssembly()
22-
.GetManifestResourceStream("ArcanumTextureSlicer.Resources.SampleTile.png")));
23-
2412
public static Point GetStartTileCenter(this Bitmap source)
2513
{
2614
var point = new Point();
@@ -34,34 +22,33 @@ public static Point GetStartTileCenter(this Bitmap source)
3422
Console.WriteLine($"Start tile color {Color.Black} is not found in palette.");
3523
return point;
3624
}
37-
var tileRows = GetTileRows();
3825
var sourceData = source.LockBits(new Rectangle(0, 0, source.Width, source.Height),
3926
ImageLockMode.ReadOnly, source.PixelFormat);
4027
try
4128
{
4229
var sourceBytes = new byte[sourceData.Height*sourceData.Stride];
4330
Marshal.Copy(sourceData.Scan0, sourceBytes, 0, sourceBytes.Length);
4431

45-
for (var y = 0; y < sourceData.Height - HalfTileHeight + 1; y++)
32+
for (var y = 0; y < sourceData.Height - Tile.HalfHeight + 1; y++)
4633
{
47-
for (var x = HalfTileWidth - 1; x < sourceData.Width - HalfTileWidth; x++)
34+
for (var x = Tile.HalfWidth - 1; x < sourceData.Width - Tile.HalfWidth; x++)
4835
{
4936
var index = y*sourceData.Stride + x;
5037
if (sourceBytes[index] == colorIndex)
5138
{
52-
for (var r = 0; r < tileRows.Length; r++)
39+
for (var r = 0; r < Tile.Rows.Length; r++)
5340
{
54-
for (var p = 0; p < tileRows[r]; p++)
41+
for (var p = 0; p < Tile.Rows[r]; p++)
5542
{
56-
var i = index + p + r*sourceData.Stride - (tileRows[r] - 2)/2;
43+
var i = index + p + r*sourceData.Stride - (Tile.Rows[r] - 2)/2;
5744
if (sourceBytes[i] != colorIndex)
5845
{
5946
goto Continue;
6047
}
6148
}
6249
}
6350
point.X = x + 1;
64-
point.Y = y + HalfTileHeight;
51+
point.Y = y + Tile.HalfHeight;
6552
goto Finish;
6653
}
6754
Continue:
@@ -79,26 +66,11 @@ public static Point GetStartTileCenter(this Bitmap source)
7966
return point;
8067
}
8168

82-
private static int[] GetTileRows()
83-
{
84-
var rows = new int[40];
85-
for (var i = 0; i < 20; i++)
86-
{
87-
rows[i] = 2 + i*4;
88-
}
89-
for (var i = 19; i >= 0; i--)
90-
{
91-
rows[39 - i] = 2 + i*4;
92-
}
93-
return rows;
94-
}
95-
96-
//private static bool
97-
9869
public static Bitmap CreateTile(this Bitmap source, int x, int y)
9970
{
100-
var tile = CloneRegion(source, new Rectangle(x, y, SampleTile.Width, SampleTile.Height));
101-
tile.DrawAlpha(SampleTile);
71+
var tile = CloneRegion(source,
72+
new Rectangle(x - Tile.HalfWidth, y - Tile.HalfHeight, Tile.Width, Tile.Height));
73+
tile.DrawAlpha();
10274
return tile;
10375
}
10476

@@ -142,43 +114,40 @@ public static void SetColor(this Bitmap canvas, byte colorIndex)
142114
}
143115
}
144116

145-
public static void DrawAlpha(this Bitmap canvas, Bitmap sample)
117+
public static void DrawAlpha(this Bitmap tile)
146118
{
147-
var rect = new Rectangle(0, 0, canvas.Width, canvas.Height);
148-
149-
var sampleData = sample.LockBits(rect, ImageLockMode.ReadOnly, sample.PixelFormat);
150-
var canvasData = canvas.LockBits(rect, ImageLockMode.WriteOnly, canvas.PixelFormat);
119+
var rect = new Rectangle(0, 0, tile.Width, tile.Height);
120+
var data = tile.LockBits(rect, ImageLockMode.WriteOnly, tile.PixelFormat);
151121
try
152122
{
153-
var sampleAlphaIndex = sample.GetColorIndex(Color.Blue);
154-
155-
var sampleBytes = new byte[sampleData.Height*sampleData.Stride];
156-
var canvasBytes = new byte[canvasData.Height*canvasData.Stride];
157-
Marshal.Copy(sampleData.Scan0, sampleBytes, 0, sampleBytes.Length);
158-
Marshal.Copy(canvasData.Scan0, canvasBytes, 0, canvasBytes.Length);
123+
var canvasBytes = new byte[data.Height*data.Stride];
124+
Marshal.Copy(data.Scan0, canvasBytes, 0, canvasBytes.Length);
159125

160-
for (var y = 0; y < canvasData.Height; y++)
126+
for (var y = 0; y < Tile.Height; y++)
161127
{
162-
for (var x = 0; x < canvasData.Width; x++)
128+
for (var x = 0; x < Tile.Width; x++)
163129
{
164-
if (sampleBytes[x + y*sampleData.Stride] == sampleAlphaIndex)
130+
if (!Tile.HitTest(x - Tile.HalfWidth, y - Tile.HalfHeight))
165131
{
166-
canvasBytes[x + y*canvasData.Stride] = 0;
132+
canvasBytes[x + y*data.Stride] = 0;
167133
}
168134
}
169135
}
170136

171-
Marshal.Copy(canvasBytes, 0, canvasData.Scan0, canvasBytes.Length);
137+
Marshal.Copy(canvasBytes, 0, data.Scan0, canvasBytes.Length);
172138
}
173139
finally
174140
{
175-
sample.UnlockBits(sampleData);
176-
canvas.UnlockBits(canvasData);
141+
tile.UnlockBits(data);
177142
}
178143
}
179144

180145
public static void DrawImage(this Bitmap canvas, Bitmap source, int canvasX, int canvasY, Rectangle sourceRect)
181146
{
147+
if (sourceRect.Width == 0 || sourceRect.Height == 0)
148+
{
149+
return;
150+
}
182151
var sourceData = source.LockBits(sourceRect, ImageLockMode.ReadOnly, source.PixelFormat);
183152
var canvasData = canvas.LockBits(new Rectangle(canvasX, canvasY, sourceRect.Width, sourceRect.Height),
184153
ImageLockMode.WriteOnly, canvas.PixelFormat);
@@ -251,5 +220,26 @@ public static bool IsTransparent(this Bitmap canvas)
251220
}
252221
return true;
253222
}
223+
224+
public static IEnumerable<Tile> ToTiles(this Bitmap bitmap, int initTileX, int initTileY)
225+
{
226+
return Tile.Split(bitmap.Width - initTileX, bitmap.Height - initTileY)
227+
.Select(t => new Tile
228+
{
229+
Row = t.Row,
230+
Column = t.Column,
231+
X = t.X + initTileX,
232+
Y = t.Y + initTileY
233+
});
234+
}
235+
236+
public static Color ToColor(this uint value)
237+
{
238+
return Color.FromArgb(
239+
(byte) ((value >> 24) & 0xFF),
240+
(byte) ((value >> 16) & 0xFF),
241+
(byte) ((value >> 8) & 0xFF),
242+
(byte) (value & 0xFF));
243+
}
254244
}
255245
}

0 commit comments

Comments
 (0)