Palettizer2/src/Program.cs

137 lines
3.7 KiB
C#

using System.CommandLine;
using System.CommandLine.Invocation;
using System.IO;
using StbImageSharp;
namespace Palettizer2
{
class Program
{
static int Main(string[] args)
{
var palettize = new Command("palettize")
{
new Argument<DirectoryInfo>(
"directory",
"Path to a directory containing PNG files."
),
new Argument<string>(
"paletteName",
"The name of the palette sprite to output."
)
};
var root = new RootCommand{
palettize
};
palettize.Handler = CommandHandler.Create<DirectoryInfo, string>(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();
// add all sprite colors to palette
foreach (var imageFile in directory.EnumerateFiles("*.png"))
{
System.Console.WriteLine(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);
}
var spriteWriteDir = Path.Combine(
outputDir.FullName,
Path.GetRelativePath(directory.FullName, spriteDir));
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);
}
}
// 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)
{
var grayscaleImage = new byte[image.Width * image.Height * 4];
for (var i = 0; i < image.Width * image.Height * 4; i += 4)
{
var color = new Color
{
R = image.Data[i],
G = image.Data[i + 1],
B = image.Data[i + 2],
A = image.Data[i + 3]
};
if (color.A == 0)
{
continue;
}
if (palette.ColorToGrayscaleMap.ContainsKey(color))
{
var grayscaleColor = palette.ColorToGrayscaleMap[color];
grayscaleImage[i] = grayscaleColor;
grayscaleImage[i + 1] = grayscaleColor;
grayscaleImage[i + 2] = grayscaleColor;
grayscaleImage[i + 3] = color.A;
}
else
{
if (palette.GrayscaleCount == 256)
{
System.Console.WriteLine("Too many colors! Bailing!");
return grayscaleImage;
}
else
{
palette.AddColor(color);
var grayscaleColor = palette.ColorToGrayscaleMap[color];
grayscaleImage[i] = grayscaleColor;
grayscaleImage[i + 1] = grayscaleColor;
grayscaleImage[i + 2] = grayscaleColor;
grayscaleImage[i + 3] = color.A;
}
}
}
return grayscaleImage;
}
}
}