From b65ea2ca6604e533fd7df06f6c15d52e43292cbd Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Tue, 30 Nov 2021 19:35:00 -0800 Subject: [PATCH] some encoding tweaks --- src/Palette.cs | 60 +++++++++++++++----------- src/Program.cs | 113 ++++++++++++++++++++++++++----------------------- 2 files changed, 95 insertions(+), 78 deletions(-) diff --git a/src/Palette.cs b/src/Palette.cs index df3a41a..fc94473 100644 --- a/src/Palette.cs +++ b/src/Palette.cs @@ -11,7 +11,7 @@ namespace Palettizer public List AlternateColorRows { get; } public int Width { get => 256; } - public int Height { get => AlternateColorRows.Count + 2; } + public int Height { get => AlternateColorRows.Count + 1; } public Palette() { @@ -36,7 +36,7 @@ namespace Palettizer break; } - increment = ((increment > 0) ? (increment + 1) : (increment - 1)) * -1; + increment = ((increment > 0) ? (increment + 1) : (increment - 1)) * -1; // up by 1, down by 2, up by 3, etc } } @@ -61,39 +61,51 @@ namespace Palettizer AlternateColorRows.Add(byteArray); } + public void ClearAlternateColorRows() + { + AlternateColorRows.Clear(); + } + public byte[] CreateIndexedPaletteBitmap() { - var paletteBitmap = new byte[256 * (AlternateColorRows.Count + 2) * 4]; + var paletteBitmap = new byte[256 * (AlternateColorRows.Count + 1) * 4]; - for (var i = 0; i < 256; i += 1) + for (var i = 0; i < 256; i += 1) { - paletteBitmap[i * 4] = (byte)i; - paletteBitmap[i * 4 + 1] = (byte)i; - paletteBitmap[i * 4 + 2] = (byte)i; - paletteBitmap[i * 4 + 3] = 255; - } + var color = new Color(); + color.A = 255; - for (var i = 0; i < 256; i += 1) - { - var color = new Color(); - if (GrayscaleToColorMap.ContainsKey((byte)i)) + if (GrayscaleToColorMap.ContainsKey((byte)i)) { - color = GrayscaleToColorMap[(byte)i]; - } - paletteBitmap[(256 + i) * 4] = color.R; - paletteBitmap[(256 + i) * 4 + 1] = color.G; - paletteBitmap[(256 + i) * 4 + 2] = color.B; - paletteBitmap[(256 + i) * 4 + 3] = color.A; - } + color = GrayscaleToColorMap[(byte)i]; + } + + paletteBitmap[i * 4] = color.R; + paletteBitmap[i * 4 + 1] = color.G; + paletteBitmap[i * 4 + 2] = color.B; + paletteBitmap[i * 4 + 3] = color.A; + } for (var i = 0; i < 256; i += 1) { for (var j = 0; j < AlternateColorRows.Count; j += 1) { - paletteBitmap[(i + (256 * (j + 2))) * 4] = AlternateColorRows[j][i * 4]; - paletteBitmap[(i + (256 * (j + 2))) * 4 + 1] = AlternateColorRows[j][i * 4 + 1]; - paletteBitmap[(i + (256 * (j + 2))) * 4 + 2] = AlternateColorRows[j][i * 4 + 2]; - paletteBitmap[(i + (256 * (j + 2))) * 4 + 3] = 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]; + } + 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; + } } } diff --git a/src/Program.cs b/src/Program.cs index 604cb93..b5fb598 100644 --- a/src/Program.cs +++ b/src/Program.cs @@ -22,9 +22,9 @@ namespace Palettizer "textureGroup", "The name of the texture group to palettize." ), - new Argument( - "paletteSpriteName", - "The palette sprite to use in indexing." + new Argument( + "paletteSpriteNames", + "A series of palette sprites to use in indexing." ) }; @@ -32,11 +32,11 @@ namespace Palettizer project }; - project.Handler = CommandHandler.Create(HandleProject); + project.Handler = CommandHandler.Create(HandleProject); return root.Invoke(args); } - static void HandleProject(FileInfo project, string textureGroup, string paletteSpriteName, IConsole console) + static void HandleProject(FileInfo project, string textureGroup, string[] paletteSpriteNames, IConsole console) { var jsonReaderOptions = new JsonDocumentOptions(); jsonReaderOptions.AllowTrailingCommas = true; @@ -103,65 +103,70 @@ namespace Palettizer } } - var paletteSpriteJSONDir = Path.Combine(projectDir.FullName, "sprites", paletteSpriteName); - var paletteSpriteJSONPath = Path.Combine(paletteSpriteJSONDir, paletteSpriteName + ".yy"); + foreach (var paletteSpriteName in paletteSpriteNames) + { + var paletteSpriteJSONDir = Path.Combine(projectDir.FullName, "sprites", paletteSpriteName); + var paletteSpriteJSONPath = Path.Combine(paletteSpriteJSONDir, paletteSpriteName + ".yy"); - var paletteSpriteData = Importer.ImportSprite(new FileInfo(paletteSpriteJSONPath)); - var paletteSpriteImagePath = Path.Combine(paletteSpriteJSONDir, paletteSpriteData.Frames[0].CompositeImage.FrameID.Name + ".png"); + var paletteSpriteData = Importer.ImportSprite(new FileInfo(paletteSpriteJSONPath)); + var paletteSpriteImagePath = Path.Combine(paletteSpriteJSONDir, paletteSpriteData.Frames[0].CompositeImage.FrameID.Name + ".png"); - // Add alternate color palettes to palette - // NOTE: our original palettes were column-indexed, we want to convert to row-index - using (var stream = File.OpenRead(paletteSpriteImagePath)) - { - ImageResult paletteImage = ImageResult.FromStream(stream, ColorComponents.RedGreenBlueAlpha); - - var indexToGrayscaleMap = new Dictionary(); - - // build the color index - for (var i = 0; i < paletteImage.Height; i += 1) + // Add alternate color palettes to palette + // NOTE: our original palettes were column-indexed, we want to convert to row-index + using (var stream = File.OpenRead(paletteSpriteImagePath)) { - var sourceColor = new Color - { - R = paletteImage.Data[i * paletteImage.Width * 4], - G = paletteImage.Data[i * paletteImage.Width * 4 + 1], - B = paletteImage.Data[i * paletteImage.Width * 4 + 2], - A = paletteImage.Data[i * paletteImage.Width * 4 + 3] - }; + ImageResult paletteImage = ImageResult.FromStream(stream, ColorComponents.RedGreenBlueAlpha); - if (palette.ColorToGrayscaleMap.ContainsKey(sourceColor)) - { - indexToGrayscaleMap.Add(i, palette.ColorToGrayscaleMap[sourceColor]); + var indexToGrayscaleMap = new Dictionary(); + + // build the color index + for (var i = 0; i < paletteImage.Height; i += 1) + { + var sourceColor = new Color + { + R = paletteImage.Data[i * paletteImage.Width * 4], + G = paletteImage.Data[i * paletteImage.Width * 4 + 1], + B = paletteImage.Data[i * paletteImage.Width * 4 + 2], + A = paletteImage.Data[i * paletteImage.Width * 4 + 3] + }; + + if (palette.ColorToGrayscaleMap.ContainsKey(sourceColor)) + { + indexToGrayscaleMap.Add(i, palette.ColorToGrayscaleMap[sourceColor]); + } + } + + for (var j = 1; j < paletteImage.Width; j += 1) + { + var colorPalette = new Color[256]; + + for (var i = 0; i < paletteImage.Height; i += 1) + { + if (!indexToGrayscaleMap.ContainsKey(i)) { continue; } + var grayscale = indexToGrayscaleMap[i]; + + colorPalette[grayscale] = new Color + { + R = paletteImage.Data[(j + i * paletteImage.Width) * 4], + G = paletteImage.Data[(j + i * paletteImage.Width) * 4 + 1], + B = paletteImage.Data[(j + i * paletteImage.Width) * 4 + 2], + A = paletteImage.Data[(j + i * paletteImage.Width) * 4 + 3] + }; + } + + palette.AddAlternateColorRow(colorPalette); } } - for (var j = 1; j < paletteImage.Width; j += 1) + // Write final palette sprite to PNG + var paletteOutputPath = Path.Combine(outputDir.FullName, textureGroup + "_" + paletteSpriteName + "_Palette.png"); + using (var stream = File.OpenWrite(paletteOutputPath)) { - var colorPalette = new Color[256]; - - for (var i = 0; i < paletteImage.Height; i += 1) - { - if (!indexToGrayscaleMap.ContainsKey(i)) { continue; } - var grayscale = indexToGrayscaleMap[i]; - - colorPalette[grayscale] = new Color - { - R = paletteImage.Data[(j + i * paletteImage.Width) * 4], - G = paletteImage.Data[(j + i * paletteImage.Width) * 4 + 1], - B = paletteImage.Data[(j + i * paletteImage.Width) * 4 + 2], - A = paletteImage.Data[(j + i * paletteImage.Width) * 4 + 3] - }; - } - - palette.AddAlternateColorRow(colorPalette); + writer.WritePng(palette.CreateIndexedPaletteBitmap(), palette.Width, palette.Height, StbImageWriteSharp.ColorComponents.RedGreenBlueAlpha, stream); } - } - // Write final palette sprite to PNG - var paletteOutputPath = Path.Combine(outputDir.FullName, textureGroup + "_Palette.png"); - using (var stream = File.OpenWrite(paletteOutputPath)) - { - writer.WritePng(palette.CreateIndexedPaletteBitmap(), palette.Width, palette.Height, StbImageWriteSharp.ColorComponents.RedGreenBlueAlpha, stream); - } + palette.ClearAlternateColorRows(); + } } static byte[] AddSpriteToPalette(Palette palette, ImageResult image, IConsole console)