various palette gen fixes
parent
1713c86afe
commit
3a5705eb17
121
src/Palette.cs
121
src/Palette.cs
|
@ -4,81 +4,98 @@ namespace Palettizer
|
||||||
{
|
{
|
||||||
public class Palette
|
public class Palette
|
||||||
{
|
{
|
||||||
public Dictionary<Color, byte> ColorToGrayscaleMap { get; }
|
public Dictionary<byte, Color> GrayscaleToColorMap { get; }
|
||||||
public byte GrayscaleIndex { get; set; }
|
public Color[] GrayscaleToColor { get; }
|
||||||
public List<byte[]> AlternateColorRows { get; }
|
public Dictionary<Color, byte> ColorToGrayscaleMap { get; }
|
||||||
|
public int GrayscaleCount { get; set; }
|
||||||
|
public List<byte[]> AlternateColorRows { get; }
|
||||||
|
|
||||||
public int Width { get => ColorToGrayscaleMap.Count; }
|
public int Width { get => 256; }
|
||||||
public int Height { get => AlternateColorRows.Count + 1; }
|
public int Height { get => AlternateColorRows.Count + 2; }
|
||||||
|
|
||||||
public Palette()
|
public Palette()
|
||||||
{
|
{
|
||||||
|
GrayscaleToColorMap = new Dictionary<byte, Color>();
|
||||||
ColorToGrayscaleMap = new Dictionary<Color, byte>();
|
ColorToGrayscaleMap = new Dictionary<Color, byte>();
|
||||||
GrayscaleIndex = 0;
|
GrayscaleCount = 0;
|
||||||
AlternateColorRows = new List<byte[]>();
|
AlternateColorRows = new List<byte[]>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddColor(Color color, byte grayscaleIndex)
|
public void AddColor(Color color)
|
||||||
{
|
{
|
||||||
ColorToGrayscaleMap.Add(color, grayscaleIndex);
|
var average = (color.R + color.G + color.B) / 3;
|
||||||
}
|
if (GrayscaleToColorMap.ContainsKey((byte)average))
|
||||||
|
{
|
||||||
|
var increment = 1;
|
||||||
|
for (var i = 0; i < 256 - GrayscaleCount; i += 1)
|
||||||
|
{
|
||||||
|
average += increment;
|
||||||
|
|
||||||
|
if (!GrayscaleToColorMap.ContainsKey((byte)average))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
increment = ((increment > 0) ? (increment + 1) : (increment - 1)) * -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
GrayscaleToColorMap.Add((byte)average, color);
|
||||||
|
ColorToGrayscaleMap.Add(color, (byte)average);
|
||||||
|
GrayscaleCount += 1;
|
||||||
|
}
|
||||||
|
|
||||||
public void AddAlternateColorRow(Color[] colors)
|
public void AddAlternateColorRow(Color[] colors)
|
||||||
{
|
{
|
||||||
var byteArray = new byte[ColorToGrayscaleMap.Count * 4];
|
var byteArray = new byte[256 * 4];
|
||||||
|
|
||||||
foreach (var color in colors)
|
for (var i = 0; i < 256; i += 1)
|
||||||
{
|
{
|
||||||
if (ColorToGrayscaleMap.ContainsKey(color))
|
byteArray[i * 4] = colors[i].R;
|
||||||
{
|
byteArray[i * 4 + 1] = colors[i].G;
|
||||||
var grayscaleIndex = ColorToGrayscaleMap[color];
|
byteArray[i * 4 + 2] = colors[i].B;
|
||||||
|
byteArray[i * 4 + 3] = colors[i].A;
|
||||||
|
}
|
||||||
|
|
||||||
byteArray[grayscaleIndex] = color.R;
|
AlternateColorRows.Add(byteArray);
|
||||||
byteArray[grayscaleIndex + 1] = color.G;
|
|
||||||
byteArray[grayscaleIndex + 2] = color.B;
|
|
||||||
byteArray[grayscaleIndex + 3] = color.A;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
System.Console.WriteLine($"Color {color.ToString()} doesn't exist in the grayscale palette!! Bailing!!!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AlternateColorRows.Add(byteArray);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] CreateIndexedPaletteBitmap()
|
public byte[] CreateIndexedPaletteBitmap()
|
||||||
{
|
{
|
||||||
var paletteBitmap = new byte[ColorToGrayscaleMap.Count * 4 * (AlternateColorRows.Count + 1)];
|
var paletteBitmap = new byte[256 * (AlternateColorRows.Count + 2) * 4];
|
||||||
|
|
||||||
var index = 0;
|
for (var i = 0; i < 256; i += 1)
|
||||||
foreach (KeyValuePair<Color, byte> kv in ColorToGrayscaleMap)
|
|
||||||
{
|
{
|
||||||
var color = kv.Key;
|
paletteBitmap[i * 4] = (byte)i;
|
||||||
var grayscale = kv.Value;
|
paletteBitmap[i * 4 + 1] = (byte)i;
|
||||||
|
paletteBitmap[i * 4 + 2] = (byte)i;
|
||||||
|
paletteBitmap[i * 4 + 3] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
paletteBitmap[index] = grayscale;
|
for (var i = 0; i < 256; i += 1)
|
||||||
paletteBitmap[index + 1] = grayscale;
|
{
|
||||||
paletteBitmap[index + 2] = grayscale;
|
var color = new Color();
|
||||||
paletteBitmap[index + 3] = 255;
|
if (GrayscaleToColorMap.ContainsKey((byte)i))
|
||||||
|
|
||||||
var alternateIndex = 1;
|
|
||||||
foreach (var alternateColorRow in AlternateColorRows)
|
|
||||||
{
|
{
|
||||||
for (var j = 0; j < ColorToGrayscaleMap.Count * 4; j += 4)
|
color = GrayscaleToColorMap[(byte)i];
|
||||||
{
|
}
|
||||||
paletteBitmap[index + (ColorToGrayscaleMap.Count * alternateIndex)] = alternateColorRow[j];
|
paletteBitmap[(256 + i) * 4] = color.R;
|
||||||
paletteBitmap[index + 1 + (ColorToGrayscaleMap.Count * alternateIndex)] = alternateColorRow[j + 1];
|
paletteBitmap[(256 + i) * 4 + 1] = color.G;
|
||||||
paletteBitmap[index + 2 + (ColorToGrayscaleMap.Count * alternateIndex)] = alternateColorRow[j + 2];
|
paletteBitmap[(256 + i) * 4 + 2] = color.B;
|
||||||
paletteBitmap[index + 3 + (ColorToGrayscaleMap.Count * alternateIndex)] = alternateColorRow[j + 3];
|
paletteBitmap[(256 + i) * 4 + 3] = color.A;
|
||||||
}
|
}
|
||||||
|
|
||||||
alternateIndex += 1;
|
for (var i = 0; i < 256; i += 1)
|
||||||
}
|
{
|
||||||
|
for (var j = 0; j < AlternateColorRows.Count; j += 1)
|
||||||
index += 4;
|
{
|
||||||
}
|
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];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return paletteBitmap;
|
return paletteBitmap;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.CommandLine;
|
using System.CommandLine;
|
||||||
using System.CommandLine.Invocation;
|
using System.CommandLine.Invocation;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
@ -114,24 +115,46 @@ namespace Palettizer
|
||||||
{
|
{
|
||||||
ImageResult paletteImage = ImageResult.FromStream(stream, ColorComponents.RedGreenBlueAlpha);
|
ImageResult paletteImage = ImageResult.FromStream(stream, ColorComponents.RedGreenBlueAlpha);
|
||||||
|
|
||||||
for (var j = 0; j < paletteImage.Width; j += 1)
|
var indexToGrayscaleMap = new Dictionary<int, byte>();
|
||||||
|
|
||||||
|
// 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[paletteImage.Height];
|
var colorPalette = new Color[256];
|
||||||
|
|
||||||
for (var i = 0; i < paletteImage.Height; i += 1)
|
for (var i = 0; i < paletteImage.Height; i += 1)
|
||||||
{
|
{
|
||||||
colorPalette[i] = new Color
|
if (!indexToGrayscaleMap.ContainsKey(i)) { continue; }
|
||||||
|
var grayscale = indexToGrayscaleMap[i];
|
||||||
|
|
||||||
|
colorPalette[grayscale] = new Color
|
||||||
{
|
{
|
||||||
R = paletteImage.Data[j * 4 + i * paletteImage.Width * 4],
|
R = paletteImage.Data[(j + i * paletteImage.Width) * 4],
|
||||||
G = paletteImage.Data[(j * 4 + i * paletteImage.Width * 4) + 1],
|
G = paletteImage.Data[(j + i * paletteImage.Width) * 4 + 1],
|
||||||
B = paletteImage.Data[(j * 4 + i * paletteImage.Width * 4) + 2],
|
B = paletteImage.Data[(j + i * paletteImage.Width) * 4 + 2],
|
||||||
A = paletteImage.Data[(j * 4 + i * paletteImage.Width * 4) + 3]
|
A = paletteImage.Data[(j + i * paletteImage.Width) * 4 + 3]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
palette.AddAlternateColorRow(colorPalette);
|
palette.AddAlternateColorRow(colorPalette);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write final palette sprite to PNG
|
// Write final palette sprite to PNG
|
||||||
var paletteOutputPath = Path.Combine(outputDir.FullName, textureGroup + "_Palette.png");
|
var paletteOutputPath = Path.Combine(outputDir.FullName, textureGroup + "_Palette.png");
|
||||||
|
@ -171,15 +194,14 @@ namespace Palettizer
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (palette.GrayscaleIndex == 255)
|
if (palette.GrayscaleCount == 256)
|
||||||
{
|
{
|
||||||
console.Out.Write("Too many colors! Bailing!\n");
|
console.Out.Write("Too many colors! Bailing!\n");
|
||||||
return grayscaleImage;
|
return grayscaleImage;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
palette.ColorToGrayscaleMap.Add(color, palette.GrayscaleIndex);
|
palette.AddColor(color);
|
||||||
palette.GrayscaleIndex += 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue