public static Image <Rgba32> ToImage(ImageInfo imageInfo, PointGetter pointGetter) { var img = new Image <Rgba32>(imageInfo.Width, imageInfo.Height); for (int i = 0; i < imageInfo.Pixels.Length; i++) { Point point = pointGetter(i, imageInfo.Width); Rgba32 color = imageInfo.Palette[imageInfo.Pixels[i]]; img[point.X, point.Y] = color; } return(img); }
public static void SaveAsPng(string file, Cell[] bank, uint blockSize, ImageInfo imageInfo, bool tiled = false, bool debug = false) { int minY = bank.Min(i => i.YOffset); int yShift = minY < 0 ? -minY : 0; int minX = bank.Min(i => i.XOffset); int xShift = minX < 0 ? -minX : 0; PointGetter pointGetter = tiled ? new PointGetter(PointUtil.GetPointTiled8) : new PointGetter(PointUtil.GetPoint); Rgba32[] palette32 = imageInfo.Palette; palette32[0] = Color.Transparent; using (var graphic = new Image <Rgba32>(imageInfo.Width, imageInfo.Height)) { for (int i = 0; i < bank.Length; i++) { Cell cell = bank[i]; if (cell.Width == 0x00 || cell.Height == 0x00) { continue; } int tileOffset = cell.TileOffset << (byte)blockSize; int bankDataOffset = 0; var startByte = tileOffset * 0x20 + bankDataOffset; byte[] cellPixels = imageInfo.Pixels.Skip(startByte).Take(cell.Width * cell.Height).ToArray(); using (var cellImg = ToImage(new ImageInfo(cellPixels, palette32, cell.Width, cell.Height), pointGetter)) { cellImg.Mutate(g => { if (cell.FlipX) { g.Flip(FlipMode.Horizontal); } if (cell.FlipY) { g.Flip(FlipMode.Vertical); } }); graphic.Mutate(g => { g.DrawImage( image: cellImg, location: new Point(cell.XOffset + xShift, cell.YOffset + yShift), opacity: 1); }); } } if (debug) { graphic.Mutate(g => { for (int i = 0; i < bank.Length; i++) { var cell = bank[i]; g.DrawText(i.ToString(), SystemFonts.CreateFont("Arial", 9), Color.Black, new PointF(cell.XOffset + 2 + xShift, cell.YOffset + 2 + yShift)); g.Draw(new Pen(Color.Red, 1), new RectangleF(cell.XOffset + xShift, cell.YOffset + yShift, cell.Width, cell.Height)); } }); } graphic.SaveAsPng(file); } }