Last active
October 9, 2021 18:01
-
-
Save michaelbramwell/88524358e7d90fab7695 to your computer and use it in GitHub Desktop.
C# Sprite Generator / Maker (zero config) - generates a sprite-sheet with css classes outputted as a string
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal class SpriteInfo | |
{ | |
public string Name { get; private set; } | |
public int X { get; private set; } | |
public int Y { get; private set; } | |
public int W { get; private set; } | |
public int H { get; private set; } | |
public SpriteInfo(string name, int x, int y, int w, int h) | |
{ | |
Name = name; | |
X = x; | |
Y = y; | |
W = w; | |
H = h; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Add images in a target dir and output as a base64 png sprite sheet referenced in a generated style sheet with css classes | |
/// Reference - http://codeinreview.com/126/generating-a-css-sprite-image-file/ | |
/// TODO: provide various sprite sorting alg options e.g tilings, vertical. Only hoz at the moment. | |
/// TODO: Provide alt return type of stream. Only string at the moment | |
/// TODO: Convert to github repo? | |
/// </summary> | |
public static class SpriteMaker | |
{ | |
public static string Execute(string path) | |
{ | |
var info = new DirectoryInfo(path); | |
var dictionary = new Dictionary<FileInfo, Image>(); | |
var padding = 10; | |
int maxWidth, maxHeight; | |
maxWidth = maxHeight = 0; | |
foreach (var file in info.GetFiles()) | |
{ | |
var img = Image.FromFile(file.FullName); | |
maxWidth += (img.Width + padding); | |
maxHeight = Math.Max(img.Height, maxHeight); | |
img.Tag = Path.GetFileNameWithoutExtension(file.FullName); | |
dictionary.Add(file, img); | |
} | |
var generated = dictionary.GenerateSprite(maxWidth, maxHeight, padding); | |
using (Bitmap sprite = generated.Key) | |
using (var memoryStream = new MemoryStream()) | |
{ | |
sprite.Save(memoryStream, ImageFormat.Png); | |
byte[] bytes = memoryStream.GetBuffer(); | |
return GenerateStyleSheet(Convert.ToBase64String(bytes, Base64FormattingOptions.None), generated); | |
} | |
} | |
/// <summary> | |
/// Iterate over each sprite and add to sprite sheet | |
/// </summary> | |
/// <param name="dictionary"></param> | |
/// <param name="maxWidth"></param> | |
/// <param name="maxHeight"></param> | |
/// <param name="padding"></param> | |
/// <returns></returns> | |
internal static KeyValuePair<Bitmap, List<SpriteInfo>> GenerateSprite(this Dictionary<FileInfo, Image> dictionary, int maxWidth, int maxHeight, int padding) | |
{ | |
var sprite = new Bitmap(maxWidth, maxHeight); | |
var spriteProps = new List<SpriteInfo>(); | |
using (Graphics graphics = Graphics.FromImage(sprite)) | |
{ | |
int xCoord = 0; | |
foreach (var kvp in dictionary) | |
{ | |
using (Image img = kvp.Value) | |
{ | |
graphics.DrawImage(img, xCoord, 0, img.Width, img.Height); | |
spriteProps.Add(new SpriteInfo(kvp.Key.Name.Replace(kvp.Key.Extension, ""), xCoord, 0, img.Width, img.Height)); | |
xCoord += (img.Width + padding); | |
} | |
} | |
return new KeyValuePair<Bitmap, List<SpriteInfo>>(sprite, spriteProps); | |
} | |
} | |
/// <summary> | |
/// Create StyleSheet with background positioning for each image | |
/// </summary> | |
/// <param name="base64SpriteSheet"></param> | |
/// <param name="kvp"></param> | |
/// <returns></returns> | |
private static string GenerateStyleSheet(string base64SpriteSheet, KeyValuePair<Bitmap, List<SpriteInfo>> kvp) | |
{ | |
var sb = new StringBuilder(); | |
// sprite sheet | |
sb.AppendFormat(".spriteSheet {{ display: inline-block; width: {0}px; height: {1}px; background: url('data:image/png;base64,{2}') no-repeat top left; }}", | |
kvp.Key.Width, kvp.Key.Height, base64SpriteSheet); | |
// descendants of sprite sheet | |
kvp.Value.Aggregate(sb, (a, b) => a.AppendLine(string.Format(".spriteSheet.{0} {{ background-position: -{1}px {2}px; width: {3}px; height: {4}px; {5} }} ", | |
b.Name, b.X, b.Y, b.W, b.H, (b.Name.Contains("display_block")) ? "display: block;" : ""))); | |
return sb.ToString(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment