diff --git a/src/Color.cs b/src/Color.cs index 885199c..238d190 100644 --- a/src/Color.cs +++ b/src/Color.cs @@ -2,14 +2,14 @@ namespace Palettizer2 { public struct Color { - public byte R { get; set; } - public byte G { get; set; } - public byte B { get; set; } - public byte A { get; set; } + public byte R; + public byte G; + public byte B; + public byte A; public override string ToString() { - return $"{{R: {R.ToString()}, G: {G.ToString()}, B: {B.ToString()}, A: {A.ToString()}}}"; - } + return $"{{R: {R.ToString()}, G: {G.ToString()}, B: {B.ToString()}, A: {A.ToString()}}}"; + } } } diff --git a/src/Palette.cs b/src/Palette.cs index 1b8f654..e778597 100644 --- a/src/Palette.cs +++ b/src/Palette.cs @@ -5,64 +5,65 @@ namespace Palettizer2 public class Palette { public Dictionary GrayscaleToColorMap { get; } - public Dictionary ColorToGrayscaleMap { get; } - public int GrayscaleCount { get; set; } - public List AlternateColorRows { get; } + public Dictionary ColorToGrayscaleMap { get; } + public int GrayscaleCount { get; set; } + public List AlternateColorRows { get; } - public int Width { get => 256; } - public int Height { get => AlternateColorRows.Count + 1; } + public const int Width = 256; + public int Height => AlternateColorRows.Count + 1; public Palette() { GrayscaleToColorMap = new Dictionary(); ColorToGrayscaleMap = new Dictionary(); - GrayscaleCount = 0; - AlternateColorRows = new List(); + GrayscaleCount = 0; + AlternateColorRows = new List(); } public void AddColor(Color color) { - var average = (color.R + color.G + color.B) / 3; + var average = (color.R + color.G + color.B) / 3; if (GrayscaleToColorMap.ContainsKey((byte)average)) { - var increment = 1; - for (var i = 0; i < 256; i += 1) + var increment = 1; + for (var i = 0; i < 256; i += 1) { - average = (average + increment) % 256; + average = (average + increment) % 256; if (!GrayscaleToColorMap.ContainsKey((byte)average)) { - break; - } + break; + } - increment = ((increment > 0) ? (increment + 1) : (increment - 1)) * -1; // up by 1, down by 2, up by 3, etc - } - } + increment = ((increment > 0) ? (increment + 1) : (increment - 1)) * + -1; // up by 1, down by 2, up by 3, etc + } + } - GrayscaleToColorMap.Add((byte)average, color); - ColorToGrayscaleMap.Add(color, (byte)average); - GrayscaleCount += 1; - } + GrayscaleToColorMap.Add((byte)average, color); + ColorToGrayscaleMap.Add(color, (byte)average); + GrayscaleCount += 1; + } public void AddAlternateColorRow(Color[] colors) { var byteArray = new byte[256 * 4]; - for (var i = 0; i < 256; i += 1) + for (var i = 0; i < 256; i += 1) { - byteArray[i * 4] = colors[i].R; - byteArray[i * 4 + 1] = colors[i].G; - byteArray[i * 4 + 2] = colors[i].B; - byteArray[i * 4 + 3] = colors[i].A; - } + byteArray[i * 4] = colors[i].R; + byteArray[i * 4 + 1] = colors[i].G; + byteArray[i * 4 + 2] = colors[i].B; + byteArray[i * 4 + 3] = colors[i].A; + } - AlternateColorRows.Add(byteArray); + AlternateColorRows.Add(byteArray); } public void ClearAlternateColorRows() { - AlternateColorRows.Clear(); - } + AlternateColorRows.Clear(); + } public byte[] CreateIndexedPaletteBitmap() { @@ -71,9 +72,9 @@ namespace Palettizer2 for (var i = 0; i < 256; i += 1) { var color = new Color(); - color.A = 255; + color.A = 255; - if (GrayscaleToColorMap.ContainsKey((byte)i)) + if (GrayscaleToColorMap.ContainsKey((byte)i)) { color = GrayscaleToColorMap[(byte)i]; } @@ -84,28 +85,28 @@ namespace Palettizer2 paletteBitmap[i * 4 + 3] = color.A; } - for (var i = 0; i < 256; i += 1) + for (var i = 0; i < 256; i += 1) { - for (var j = 0; j < AlternateColorRows.Count; j += 1) + for (var j = 0; j < AlternateColorRows.Count; j += 1) { - var alpha = AlternateColorRows[j][i * 4 + 3]; + var alpha = AlternateColorRows[j][i * 4 + 3]; if (alpha == 0) { // grab from top row - paletteBitmap[(i + (256 * (j + 1))) * 4] = paletteBitmap[i * 4]; - paletteBitmap[(i + (256 * (j + 1))) * 4 + 1] = paletteBitmap[i * 4 + 1]; - paletteBitmap[(i + (256 * (j + 1))) * 4 + 2] = paletteBitmap[i * 4 + 2]; - paletteBitmap[(i + (256 * (j + 1))) * 4 + 3] = paletteBitmap[i * 4 + 3]; + paletteBitmap[(i + (256 * (j + 1))) * 4] = paletteBitmap[i * 4]; + paletteBitmap[(i + (256 * (j + 1))) * 4 + 1] = paletteBitmap[i * 4 + 1]; + paletteBitmap[(i + (256 * (j + 1))) * 4 + 2] = paletteBitmap[i * 4 + 2]; + paletteBitmap[(i + (256 * (j + 1))) * 4 + 3] = paletteBitmap[i * 4 + 3]; } - else - { - paletteBitmap[(i + (256 * (j + 1))) * 4] = AlternateColorRows[j][i * 4]; - paletteBitmap[(i + (256 * (j + 1))) * 4 + 1] = AlternateColorRows[j][i * 4 + 1]; - paletteBitmap[(i + (256 * (j + 1))) * 4 + 2] = AlternateColorRows[j][i * 4 + 2]; - paletteBitmap[(i + (256 * (j + 1))) * 4 + 3] = alpha; - } - } - } + else + { + paletteBitmap[(i + (256 * (j + 1))) * 4] = AlternateColorRows[j][i * 4]; + paletteBitmap[(i + (256 * (j + 1))) * 4 + 1] = AlternateColorRows[j][i * 4 + 1]; + paletteBitmap[(i + (256 * (j + 1))) * 4 + 2] = AlternateColorRows[j][i * 4 + 2]; + paletteBitmap[(i + (256 * (j + 1))) * 4 + 3] = alpha; + } + } + } return paletteBitmap; } diff --git a/src/Program.cs b/src/Program.cs index 1627f52..d221459 100644 --- a/src/Program.cs +++ b/src/Program.cs @@ -5,83 +5,84 @@ using StbImageSharp; namespace Palettizer2 { - class Program - { - static int Main(string[] args) - { - var palettize = new Command("palettize") - { - new Argument( - "directory", - "Path to a directory containing PNG files." - ), + class Program + { + static int Main(string[] args) + { + var palettize = new Command("palettize") + { + new Argument( + "directory", + "Path to a directory containing PNG files." + ), new Argument( "paletteName", "The name of the palette sprite to output." ) - }; + }; - var root = new RootCommand{ - palettize - }; + var root = new RootCommand + { + palettize + }; - palettize.Handler = CommandHandler.Create(HandlePalettize); - return root.Invoke(args); - } + palettize.Handler = CommandHandler.Create(HandlePalettize); + return root.Invoke(args); + } - static void HandlePalettize(DirectoryInfo directory, string paletteName) - { - var outputDir = Directory.CreateDirectory("output"); - var palette = new Palette(); - var writer = new StbImageWriteSharp.ImageWriter(); + static void HandlePalettize(DirectoryInfo directory, string paletteName) + { + var outputDir = Directory.CreateDirectory("output"); + var palette = new Palette(); + var writer = new StbImageWriteSharp.ImageWriter(); - // add all sprite colors to palette - foreach (var imageFile in directory.EnumerateFiles("*.png", SearchOption.AllDirectories)) - { - System.Console.WriteLine(imageFile.FullName); + // add all sprite colors to palette + foreach (var imageFile in directory.EnumerateFiles("*.png", SearchOption.AllDirectories)) + { + System.Console.WriteLine(imageFile.FullName); - var spriteDir = Path.GetDirectoryName(imageFile.FullName); + var spriteDir = Path.GetDirectoryName(imageFile.FullName); - ImageResult image; - byte[] grayscaleImageBytes; - using (var stream = File.OpenRead(imageFile.FullName)) - { - image = ImageResult.FromStream(stream, ColorComponents.RedGreenBlueAlpha); - grayscaleImageBytes = AddSpriteToPalette(palette, image); - } + ImageResult image; + byte[] grayscaleImageBytes; + using (var stream = File.OpenRead(imageFile.FullName)) + { + image = ImageResult.FromStream(stream, ColorComponents.RedGreenBlueAlpha); + grayscaleImageBytes = AddSpriteToPalette(palette, image); + } - var spriteWriteDir = Path.Combine( - outputDir.FullName, - Path.GetRelativePath(directory.FullName, spriteDir)); + var spriteWriteDir = Path.Combine( + outputDir.FullName, + Path.GetRelativePath(directory.FullName, spriteDir)); - Directory.CreateDirectory(spriteWriteDir); - var spriteWritePath = Path.Combine(spriteWriteDir, imageFile.Name); + Directory.CreateDirectory(spriteWriteDir); + var spriteWritePath = Path.Combine(spriteWriteDir, imageFile.Name); - using (var stream = File.OpenWrite(spriteWritePath)) - { - writer.WritePng( - grayscaleImageBytes, - image.Width, - image.Height, - StbImageWriteSharp.ColorComponents.RedGreenBlueAlpha, - stream); - } - } + using (var stream = File.OpenWrite(spriteWritePath)) + { + writer.WritePng( + grayscaleImageBytes, + image.Width, + image.Height, + StbImageWriteSharp.ColorComponents.RedGreenBlueAlpha, + stream); + } + } - // write palette sprite to PNG - var paletteOutputPath = Path.Combine(outputDir.FullName, paletteName + ".png"); - using (var stream = File.OpenWrite(paletteOutputPath)) - { - writer.WritePng( - palette.CreateIndexedPaletteBitmap(), - palette.Width, - palette.Height, - StbImageWriteSharp.ColorComponents.RedGreenBlueAlpha, - stream); - } - } + // write palette sprite to PNG + var paletteOutputPath = Path.Combine(outputDir.FullName, paletteName + ".png"); + using (var stream = File.OpenWrite(paletteOutputPath)) + { + writer.WritePng( + palette.CreateIndexedPaletteBitmap(), + Palette.Width, + palette.Height, + StbImageWriteSharp.ColorComponents.RedGreenBlueAlpha, + stream); + } + } - static byte[] AddSpriteToPalette(Palette palette, ImageResult image) + static byte[] AddSpriteToPalette(Palette palette, ImageResult image) { var grayscaleImage = new byte[image.Width * image.Height * 4]; @@ -118,7 +119,7 @@ namespace Palettizer2 } else { - palette.AddColor(color); + palette.AddColor(color); var grayscaleColor = palette.ColorToGrayscaleMap[color]; @@ -132,5 +133,5 @@ namespace Palettizer2 return grayscaleImage; } - } + } }