Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

C# SpriteSheet Reader & Parser

0.00/5 (No votes)
31 Aug 2012 1  
Code to read and parse a spritesheet coordinates file and extract the corresponding sprites from it

Introduction

This brief code is meant to read and parse a spritesheet coordinates file and extract its corresponding Image objects. I wrote it to be able to use spritesheets generated with TexturePacker and may be compatible with other tools.

Background

A spritesheet is an Image which contains smaller images like a map, to be used especially in games.

What is a sprite sheet?

Using the Code

A small class called Spritesheet with a static factory method LoadSpriteSheet to parse a coordinates (XML) file.

It holds a Dictionary to map the spriteFrameName to the actual Image it represents.

class Spritesheet
    {
        public string Name { get; set; }
        public Dictionary<string, Image> Sprites { get; set; }

        public Spritesheet(string spriteSheetName)
        {
            this.Sprites = new Dictionary<string, Image>(50);
            this.Name = spriteSheetName;
        }

        public static Spritesheet LoadSpriteSheet(string coordinatesFile)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(coordinatesFile);
            XmlNode metadata = doc.SelectSingleNode("/plist/dict/key[.='metadata']");
            XmlNode realTextureFileName = 
            metadata.NextSibling.SelectSingleNode("key[.='realTextureFileName']");
            string spritesheetName = realTextureFileName.NextSibling.InnerText;
            Image spriteSheetImage = Image.FromFile(spritesheetName);
            XmlNode frames = doc.SelectSingleNode("/plist/dict/key[.='frames']");
            XmlNodeList list = frames.NextSibling.SelectNodes("key");

            Spritesheet spritesheet = new Spritesheet(coordinatesFile);

            foreach (XmlNode node in list)
            {
                XmlNode dict = node.NextSibling;
                string strRectangle = dict.SelectSingleNode
                ("key[.='frame']").NextSibling.InnerText;
                string strOffset = dict.SelectSingleNode
                ("key[.='offset']").NextSibling.InnerText;
                string strSourceRect = dict.SelectSingleNode
                ("key[.='sourceColorRect']").NextSibling.InnerText;
                string strSourceSize = dict.SelectSingleNode
                ("key[.='sourceSize']").NextSibling.InnerText;
                Rectangle frame = parseRectangle(strRectangle);
                Point offset = parsePoint(strOffset);
                Rectangle sourceRectangle = parseRectangle(strSourceRect);
                Point size = parsePoint(strSourceSize);

                string spriteFrameName = node.InnerText;
                Image sprite = new Bitmap(size.X, size.Y);
                Graphics drawer = Graphics.FromImage(sprite);
                drawer.DrawImage(spriteSheetImage, sourceRectangle, frame, GraphicsUnit.Pixel);
                drawer.Save();
                drawer.Dispose();
                spritesheet.Sprites.Add(spriteFrameName, sprite);
            }
            return spritesheet;
        }

        private static Rectangle parseRectangle(string rectangle)
        {
            Regex expression = new Regex(@"\{\{(\d+),(\d+)\},\{(\d+),(\d+)\}\}");
            Match match = expression.Match(rectangle);
            if (match.Success)
            {
                int x = int.Parse(match.Groups[1].Value);
                int y = int.Parse(match.Groups[2].Value);
                int w = int.Parse(match.Groups[3].Value);
                int h = int.Parse(match.Groups[4].Value);
                return new Rectangle(x, y, w, h);
            }
            return Rectangle.Empty;
        }

        private static Point parsePoint(string point)
        {
            Regex expression = new Regex(@"\{(\d+),(\d+)\}");
            Match match = expression.Match(point);
            if (match.Success)
            {
                int x = int.Parse(match.Groups[1].Value);
                int y = int.Parse(match.Groups[2].Value);
                return new Point(x, y);
            }
            return Point.Empty;
        }
    } 

Here is a usage example:

OpenFileDialog dialog = new OpenFileDialog();
dialog.Filter = "property list (*.plist)|*.plist|XML files (*.xml)|
*.xml|Supported Files|*.xml;*.plist";
dialog.FilterIndex = 3;
if (dialog.ShowDialog(this) == DialogResult.OK)
{	
	Spritesheet spritesheet = Spritesheet.LoadSpriteSheet(dialog.FileName);
	//TODO
} 

History

  • Initial post, basic usage guidelines

Note: Doesn't support sprite rotation, yet!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here