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