Minor bug fixes.
This commit is contained in:
@@ -55,6 +55,8 @@ public static class Program
|
||||
string? currentList = null;
|
||||
string itemName = "";
|
||||
int tileW = 0, tileH = 0;
|
||||
bool transparent = false;
|
||||
string transparentColor = "clBlack";
|
||||
StringBuilder? hex = null;
|
||||
byte[]? pictureData = null;
|
||||
int itemIndex = 0;
|
||||
@@ -64,7 +66,8 @@ public static class Program
|
||||
if (currentList == null || pictureData == null) return;
|
||||
string safeName = itemName.Length > 0 ? itemName : "unnamed";
|
||||
string file = $"{currentList.ToLowerInvariant()}_{itemIndex:D2}_{safeName}.png";
|
||||
SaveGraphic(pictureData, Path.Combine(_outDir, "gfx", file));
|
||||
SaveGraphic(pictureData, Path.Combine(_outDir, "gfx", file),
|
||||
transparent ? ParseDelphiColor(transparentColor) : null);
|
||||
manifest.TryAdd(currentList, []);
|
||||
// TileWidth/TileHeight of 0 means "whole image is one frame"
|
||||
manifest[currentList].Add(new ImageItem(itemIndex, itemName, file, tileW, tileH));
|
||||
@@ -73,6 +76,8 @@ public static class Program
|
||||
pictureData = null;
|
||||
itemName = "";
|
||||
tileW = tileH = 0;
|
||||
transparent = false;
|
||||
transparentColor = "clBlack";
|
||||
}
|
||||
|
||||
foreach (var raw in lines)
|
||||
@@ -116,6 +121,10 @@ public static class Program
|
||||
tileW = int.Parse(line["TileWidth = ".Length..]);
|
||||
else if (line.StartsWith("TileHeight = "))
|
||||
tileH = int.Parse(line["TileHeight = ".Length..]);
|
||||
else if (line.StartsWith("TransparentColor = "))
|
||||
transparentColor = line["TransparentColor = ".Length..];
|
||||
else if (line == "Transparent = True")
|
||||
transparent = true;
|
||||
else if (line.StartsWith("Picture.Data = {"))
|
||||
hex = new StringBuilder(line["Picture.Data = {".Length..]);
|
||||
}
|
||||
@@ -126,8 +135,27 @@ public static class Program
|
||||
Console.WriteLine(" wrote gfx/manifest.json");
|
||||
}
|
||||
|
||||
/// <summary>Delphi TColor: 0x00BBGGRR integer or a clXxx name.</summary>
|
||||
static Color ParseDelphiColor(string value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case "clBlack": return Color.FromArgb(0, 0, 0);
|
||||
case "clWhite": return Color.FromArgb(255, 255, 255);
|
||||
case "clRed": return Color.FromArgb(255, 0, 0);
|
||||
case "clLime": return Color.FromArgb(0, 255, 0);
|
||||
case "clBlue": return Color.FromArgb(0, 0, 255);
|
||||
case "clNavy": return Color.FromArgb(0, 0, 128);
|
||||
case "clFuchsia": return Color.FromArgb(255, 0, 255);
|
||||
case "clYellow": return Color.FromArgb(255, 255, 0);
|
||||
case "clAqua": return Color.FromArgb(0, 255, 255);
|
||||
}
|
||||
int v = int.Parse(value);
|
||||
return Color.FromArgb(v & 0xFF, (v >> 8) & 0xFF, (v >> 16) & 0xFF);
|
||||
}
|
||||
|
||||
/// <summary>Delphi TPicture blob: [1B class-name length][class name][payload].</summary>
|
||||
static void SaveGraphic(byte[] data, string outPath)
|
||||
static void SaveGraphic(byte[] data, string outPath, Color? colorKey)
|
||||
{
|
||||
int nameLen = data[0];
|
||||
string cls = Encoding.ASCII.GetString(data, 1, nameLen);
|
||||
@@ -135,14 +163,21 @@ public static class Program
|
||||
|
||||
if (cls == "TPNGObject")
|
||||
{
|
||||
File.WriteAllBytes(outPath, data[payloadStart..]);
|
||||
// PNGs keep their native alpha (Omega honored it); key applies on top if set
|
||||
byte[] png = data[payloadStart..];
|
||||
if (colorKey != null)
|
||||
SaveWithColorKey(png, outPath, colorKey.Value);
|
||||
else
|
||||
File.WriteAllBytes(outPath, png);
|
||||
}
|
||||
else if (cls == "TBitmap")
|
||||
{
|
||||
// payload: [4B length][BMP bytes]
|
||||
// payload: [4B length][BMP bytes]; key only when the item was marked Transparent
|
||||
int len = BitConverter.ToInt32(data, payloadStart);
|
||||
var bmpBytes = new ReadOnlySpan<byte>(data, payloadStart + 4, len);
|
||||
SaveBmpAsKeyedPng(bmpBytes.ToArray(), outPath);
|
||||
var bmpBytes = new ReadOnlySpan<byte>(data, payloadStart + 4, len).ToArray();
|
||||
using var ms = new MemoryStream(bmpBytes);
|
||||
using var src = new Bitmap(ms);
|
||||
SaveKeyed(src, outPath, colorKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -150,6 +185,27 @@ public static class Program
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Re-encode as PNG with the given color made fully transparent (Omega's Transparent=True).</summary>
|
||||
static void SaveWithColorKey(byte[] imageBytes, string outPath, Color key)
|
||||
{
|
||||
using var ms = new MemoryStream(imageBytes);
|
||||
using var src = new Bitmap(ms);
|
||||
SaveKeyed(src, outPath, key);
|
||||
}
|
||||
|
||||
static void SaveKeyed(Bitmap src, string outPath, Color? key)
|
||||
{
|
||||
using var dst = new Bitmap(src.Width, src.Height, PixelFormat.Format32bppArgb);
|
||||
for (int y = 0; y < src.Height; y++)
|
||||
for (int x = 0; x < src.Width; x++)
|
||||
{
|
||||
var c = src.GetPixel(x, y);
|
||||
bool keyed = key != null && c.A > 0 && c.R == key.Value.R && c.G == key.Value.G && c.B == key.Value.B;
|
||||
dst.SetPixel(x, y, keyed ? Color.Transparent : c);
|
||||
}
|
||||
dst.Save(outPath, ImageFormat.Png);
|
||||
}
|
||||
|
||||
/// <summary>Convert BMP to PNG, keying out the bottom-left pixel color (Delphi Transparent convention).</summary>
|
||||
static void SaveBmpAsKeyedPng(byte[] bmpBytes, string outPath)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user