using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; public static class SplitSprites { // Split a transparent PNG holding several objects side by side into one trimmed PNG per object // (columns separated by at least `gap` fully transparent columns), each scaled to fit maxH. public static void Run(string src, string dstPrefix, int gap, int maxH) { using (var b = new Bitmap(src)) { int w = b.Width, h = b.Height; var col = new bool[w]; var rect = new Rectangle(0, 0, w, h); var data = b.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); var px = new byte[w * h * 4]; System.Runtime.InteropServices.Marshal.Copy(data.Scan0, px, 0, px.Length); b.UnlockBits(data); for (int x = 0; x < w; x++) for (int y = 0; y < h; y++) if (px[(y * w + x) * 4 + 3] > 16) { col[x] = true; break; } var runs = new List(); int s = -1, lastOn = -1000; for (int x = 0; x < w; x++) { if (!col[x]) continue; if (s < 0) s = x; else if (x - lastOn > gap) { runs.Add(new[] { s, lastOn }); s = x; } lastOn = x; } if (s >= 0) runs.Add(new[] { s, lastOn }); int n = 0; foreach (var r in runs) { int top = h, bot = 0; for (int x = r[0]; x <= r[1]; x++) for (int y = 0; y < h; y++) if (px[(y * w + x) * 4 + 3] > 16) { if (y < top) top = y; if (y > bot) bot = y; } int cw = r[1] - r[0] + 1, ch = bot - top + 1; double k = Math.Min(1.0, maxH / (double)ch); int ow = (int)Math.Round(cw * k), oh = (int)Math.Round(ch * k); n++; using (var o = new Bitmap(ow, oh, PixelFormat.Format32bppArgb)) using (var g = Graphics.FromImage(o)) { g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; g.Clear(Color.Transparent); g.DrawImage(b, new Rectangle(0, 0, ow, oh), new Rectangle(r[0], top, cw, ch), GraphicsUnit.Pixel); o.Save(dstPrefix + n + ".png", ImageFormat.Png); } Console.WriteLine(n + ": x " + r[0] + "-" + r[1] + " y " + top + "-" + bot + " -> " + ow + "x" + oh); } } } }