private void ApplyEdgeProcessFast(TextureEdgeProcess edge, FastBitmap f, Bitmap s, Node n) { if (edge == TextureEdgeProcess.Expand1Px) { if (Padding < 2) // partL expand 1px to right, partR expand 1px to left, therefore 2px needed { throw new ArgumentOutOfRangeException(nameof(edge), "Padding must > 2 when using Texture Edge Expand"); } //source: pick a slice from part; dest: put slice to atlas //top f.CopyRegion(s, new Rectangle(0, 0, s.Width, 1), new Rectangle(n.Bounds.X, n.Bounds.Y - 1, s.Width, 1)); //down f.CopyRegion(s, new Rectangle(0, s.Height - 1, s.Width, 1), new Rectangle(n.Bounds.X, n.Bounds.Y + n.Bounds.Height, s.Width, 1)); //left f.CopyRegion(s, new Rectangle(0, 0, 1, s.Height), new Rectangle(n.Bounds.X - 1, n.Bounds.Y, 1, s.Height)); //right f.CopyRegion(s, new Rectangle(s.Width - 1, 0, 1, s.Height), new Rectangle(n.Bounds.X + n.Bounds.Width, n.Bounds.Y, 1, s.Height)); } }
public Image ToImage(bool debugMode = false, TextureEdgeProcess edge = TextureEdgeProcess.None, Color?background = null) { var bgColor = background ?? Color.FromArgb(0, Color.Black); Bitmap img = new Bitmap(Width, Height, PixelFormat.Format32bppArgb); //avoid using Graphics #if USE_FASTBITMAP if (!debugMode) { using (var f = img.FastLock()) { if (background != null) { f.Clear(bgColor); } foreach (Node n in Nodes) { if (n.Texture != null) { Image sourceImg = n.Texture.SourceImage ?? new Bitmap(n.Texture.Source); if (!(sourceImg is Bitmap s)) { s = new Bitmap(sourceImg); } f.CopyRegion(s, new Rectangle(0, 0, s.Width, s.Height), n.Bounds); ApplyEdgeProcessFast(edge, f, s, n); } } } //img.Save("tex.png", ImageFormat.png); return(img); } #endif Graphics g = Graphics.FromImage(img); g.Clear(bgColor); //g.PixelOffsetMode = PixelOffsetMode.Half; //g.InterpolationMode = InterpolationMode.Default; //g.SmoothingMode = SmoothingMode.None; //ImageAttributes attributes = new ImageAttributes(); //attributes.SetWrapMode(WrapMode.TileFlipXY); if (debugMode) { g.FillRectangle(Brushes.Green, new Rectangle(0, 0, Width, Height)); } foreach (Node n in Nodes) { if (n.Texture != null) { Image sourceImg = n.Texture.SourceImage ?? new Bitmap(n.Texture.Source); #if USE_FASTBITMAP using (var f = img.FastLock()) { if (!(sourceImg is Bitmap s)) { s = new Bitmap(sourceImg); } f.CopyRegion(s, new Rectangle(0, 0, s.Width, s.Height), n.Bounds); ApplyEdgeProcessFast(edge, f, s, n); } #else g.DrawImage(sourceImg, n.Bounds); //g.DrawImage(sourceImg, n.Bounds, 0,0, sourceImg.Width, sourceImg.Height, GraphicsUnit.Pixel, attributes); #endif if (debugMode) { string label = Path.GetFileNameWithoutExtension(n.Texture.Source); SizeF labelBox = g.MeasureString(label, SystemFonts.MenuFont, new SizeF(n.Bounds.Size)); RectangleF rectBounds = new Rectangle(n.Bounds.Location, new Size((int)labelBox.Width, (int)labelBox.Height)); g.FillRectangle(Brushes.Black, rectBounds); g.DrawString(label, SystemFonts.MenuFont, Brushes.White, rectBounds); } } else { g.FillRectangle(Brushes.DarkMagenta, n.Bounds); if (debugMode) { string label = n.Bounds.Width + "x" + n.Bounds.Height; SizeF labelBox = g.MeasureString(label, SystemFonts.MenuFont, new SizeF(n.Bounds.Size)); RectangleF rectBounds = new Rectangle(n.Bounds.Location, new Size((int)labelBox.Width, (int)labelBox.Height)); g.FillRectangle(Brushes.Black, rectBounds); g.DrawString(label, SystemFonts.MenuFont, Brushes.White, rectBounds); } } } return(img); }