some encoding tweaks
parent
3a5705eb17
commit
b65ea2ca66
|
@ -11,7 +11,7 @@ namespace Palettizer
|
||||||
public List<byte[]> AlternateColorRows { get; }
|
public List<byte[]> AlternateColorRows { get; }
|
||||||
|
|
||||||
public int Width { get => 256; }
|
public int Width { get => 256; }
|
||||||
public int Height { get => AlternateColorRows.Count + 2; }
|
public int Height { get => AlternateColorRows.Count + 1; }
|
||||||
|
|
||||||
public Palette()
|
public Palette()
|
||||||
{
|
{
|
||||||
|
@ -36,7 +36,7 @@ namespace Palettizer
|
||||||
break;
|
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);
|
AlternateColorRows.Add(byteArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ClearAlternateColorRows()
|
||||||
|
{
|
||||||
|
AlternateColorRows.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
public byte[] CreateIndexedPaletteBitmap()
|
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;
|
var color = new Color();
|
||||||
paletteBitmap[i * 4 + 1] = (byte)i;
|
color.A = 255;
|
||||||
paletteBitmap[i * 4 + 2] = (byte)i;
|
|
||||||
paletteBitmap[i * 4 + 3] = 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < 256; i += 1)
|
if (GrayscaleToColorMap.ContainsKey((byte)i))
|
||||||
{
|
|
||||||
var color = new Color();
|
|
||||||
if (GrayscaleToColorMap.ContainsKey((byte)i))
|
|
||||||
{
|
{
|
||||||
color = GrayscaleToColorMap[(byte)i];
|
color = GrayscaleToColorMap[(byte)i];
|
||||||
}
|
}
|
||||||
paletteBitmap[(256 + i) * 4] = color.R;
|
|
||||||
paletteBitmap[(256 + i) * 4 + 1] = color.G;
|
paletteBitmap[i * 4] = color.R;
|
||||||
paletteBitmap[(256 + i) * 4 + 2] = color.B;
|
paletteBitmap[i * 4 + 1] = color.G;
|
||||||
paletteBitmap[(256 + i) * 4 + 3] = color.A;
|
paletteBitmap[i * 4 + 2] = color.B;
|
||||||
}
|
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)
|
||||||
{
|
{
|
||||||
paletteBitmap[(i + (256 * (j + 2))) * 4] = AlternateColorRows[j][i * 4];
|
var alpha = AlternateColorRows[j][i * 4 + 3];
|
||||||
paletteBitmap[(i + (256 * (j + 2))) * 4 + 1] = AlternateColorRows[j][i * 4 + 1];
|
if (alpha == 0)
|
||||||
paletteBitmap[(i + (256 * (j + 2))) * 4 + 2] = AlternateColorRows[j][i * 4 + 2];
|
{
|
||||||
paletteBitmap[(i + (256 * (j + 2))) * 4 + 3] = AlternateColorRows[j][i * 4 + 3];
|
// 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
113
src/Program.cs
113
src/Program.cs
|
@ -22,9 +22,9 @@ namespace Palettizer
|
||||||
"textureGroup",
|
"textureGroup",
|
||||||
"The name of the texture group to palettize."
|
"The name of the texture group to palettize."
|
||||||
),
|
),
|
||||||
new Argument<string>(
|
new Argument<string[]>(
|
||||||
"paletteSpriteName",
|
"paletteSpriteNames",
|
||||||
"The palette sprite to use in indexing."
|
"A series of palette sprites to use in indexing."
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -32,11 +32,11 @@ namespace Palettizer
|
||||||
project
|
project
|
||||||
};
|
};
|
||||||
|
|
||||||
project.Handler = CommandHandler.Create<FileInfo, string, string, IConsole>(HandleProject);
|
project.Handler = CommandHandler.Create<FileInfo, string, string[], IConsole>(HandleProject);
|
||||||
return root.Invoke(args);
|
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();
|
var jsonReaderOptions = new JsonDocumentOptions();
|
||||||
jsonReaderOptions.AllowTrailingCommas = true;
|
jsonReaderOptions.AllowTrailingCommas = true;
|
||||||
|
@ -103,65 +103,70 @@ namespace Palettizer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var paletteSpriteJSONDir = Path.Combine(projectDir.FullName, "sprites", paletteSpriteName);
|
foreach (var paletteSpriteName in paletteSpriteNames)
|
||||||
var paletteSpriteJSONPath = Path.Combine(paletteSpriteJSONDir, paletteSpriteName + ".yy");
|
{
|
||||||
|
var paletteSpriteJSONDir = Path.Combine(projectDir.FullName, "sprites", paletteSpriteName);
|
||||||
|
var paletteSpriteJSONPath = Path.Combine(paletteSpriteJSONDir, paletteSpriteName + ".yy");
|
||||||
|
|
||||||
var paletteSpriteData = Importer.ImportSprite(new FileInfo(paletteSpriteJSONPath));
|
var paletteSpriteData = Importer.ImportSprite(new FileInfo(paletteSpriteJSONPath));
|
||||||
var paletteSpriteImagePath = Path.Combine(paletteSpriteJSONDir, paletteSpriteData.Frames[0].CompositeImage.FrameID.Name + ".png");
|
var paletteSpriteImagePath = Path.Combine(paletteSpriteJSONDir, paletteSpriteData.Frames[0].CompositeImage.FrameID.Name + ".png");
|
||||||
|
|
||||||
// Add alternate color palettes to palette
|
// Add alternate color palettes to palette
|
||||||
// NOTE: our original palettes were column-indexed, we want to convert to row-index
|
// NOTE: our original palettes were column-indexed, we want to convert to row-index
|
||||||
using (var stream = File.OpenRead(paletteSpriteImagePath))
|
using (var stream = File.OpenRead(paletteSpriteImagePath))
|
||||||
{
|
|
||||||
ImageResult paletteImage = ImageResult.FromStream(stream, ColorComponents.RedGreenBlueAlpha);
|
|
||||||
|
|
||||||
var indexToGrayscaleMap = new Dictionary<int, byte>();
|
|
||||||
|
|
||||||
// build the color index
|
|
||||||
for (var i = 0; i < paletteImage.Height; i += 1)
|
|
||||||
{
|
{
|
||||||
var sourceColor = new Color
|
ImageResult paletteImage = ImageResult.FromStream(stream, ColorComponents.RedGreenBlueAlpha);
|
||||||
{
|
|
||||||
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))
|
var indexToGrayscaleMap = new Dictionary<int, byte>();
|
||||||
{
|
|
||||||
indexToGrayscaleMap.Add(i, palette.ColorToGrayscaleMap[sourceColor]);
|
// 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];
|
writer.WritePng(palette.CreateIndexedPaletteBitmap(), palette.Width, palette.Height, StbImageWriteSharp.ColorComponents.RedGreenBlueAlpha, stream);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Write final palette sprite to PNG
|
palette.ClearAlternateColorRows();
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static byte[] AddSpriteToPalette(Palette palette, ImageResult image, IConsole console)
|
static byte[] AddSpriteToPalette(Palette palette, ImageResult image, IConsole console)
|
||||||
|
|
Loading…
Reference in New Issue