diff --git a/SpritePacker-GUI/MainWindow.cs b/SpritePacker-GUI/MainWindow.cs
index 4fba291..307dc45 100644
--- a/SpritePacker-GUI/MainWindow.cs
+++ b/SpritePacker-GUI/MainWindow.cs
@@ -6,6 +6,9 @@ using Gtk;
using Ext.SilentorBit;
using System.Drawing.Imaging;
using System.Runtime.ExceptionServices;
+using System.Drawing;
+using System.IO;
+using System.Text;
namespace SpritePacker.GUI
{
@@ -19,6 +22,9 @@ namespace SpritePacker.GUI
private Button openImageButton;
private Button removeImageButton;
+ private Button saveResultButton;
+
+ private Gtk.Image previewImage;
private SpritePacker spritePacker = new SpritePacker();
@@ -62,6 +68,7 @@ namespace SpritePacker.GUI
VBox rightPanel = new VBox(false, 0) { MarginLeft = 5 };
Frame leftPanelFrame = new Frame("Sprites") { Child = leftPanel, Margin = 10, MarginRight = 5 };
Frame rightPanelFrame = new Frame("Preview") { Child = rightPanel, Margin = 10, MarginLeft = 5 };
+ previewImage = new Gtk.Image() { Margin = 10 };
// Create the file selector filter
spriteListSelectorFilter = new FileFilter() { Name = "Images" };
@@ -84,6 +91,7 @@ namespace SpritePacker.GUI
openImageButton = new Button("Add Sprites") { Margin = 10, MarginTop = 0, MarginBottom = 0 };
removeImageButton = new Button("Remove Selected Sprites") { Margin = 10, MarginTop = 0, MarginBottom = 0 };
+ saveResultButton = new Button("Save Result") { Margin = 10 };
openImageButton.Released += (object sender, EventArgs e) => {
ResponseType response = (ResponseType)spriteListSelector.Run();
spriteListSelector.Hide();
@@ -107,6 +115,11 @@ namespace SpritePacker.GUI
foreach(Sprite currentSprite in spritePacker.CurrentSprites)
spriteListDisplay.AddItem(currentSprite);
};
+ saveResultButton.Released += (object sender, EventArgs e) => {
+ Console.WriteLine("Save image button clicked");
+ };
+
+ updatePreviewImage();
// Populate the control button row
controlButtonRow.PackStart(openImageButton, true, false, 0);
@@ -116,6 +129,10 @@ namespace SpritePacker.GUI
leftPanel.PackStart(controlButtonRow, false, false, 5);
leftPanel.PackStart(spriteListDisplay, true, true, 0);
+ // Populate the right panel
+ rightPanel.PackStart(previewImage, true, false, 10);
+ rightPanel.PackStart(saveResultButton, false, false, 10);
+
// Pack the master container
masterContainer.PackStart(leftPanelFrame, true, true, 0);
masterContainer.PackStart(rightPanelFrame, true, true, 0);
@@ -124,7 +141,7 @@ namespace SpritePacker.GUI
Add(masterContainer);
}
- void Action_AddSprite(string[] selectedFilenames)
+ private void Action_AddSprite(string[] selectedFilenames)
{
foreach (string filename in selectedFilenames)
{
@@ -132,6 +149,28 @@ namespace SpritePacker.GUI
spritePacker.Add(nextSprite);
spriteListDisplay.AddItem(nextSprite);
}
+ updatePreviewImage();
+ }
+
+ private void updatePreviewImage()
+ {
+ // TODO: Add an option to call this method manually instead of automatically
+ spritePacker.Arrange();
+
+ using(Bitmap newPreviewImage = spritePacker.GenerateImage())
+ using(MemoryStream newPreviewImageData = new MemoryStream())
+ {
+ // If the new preview image is null, then we shouldn't bother continuing
+ if (newPreviewImage == null)
+ return;
+
+ Bitmap resizedPreviewImage = SBRLUtilities.ImageTools.ResizeImage(newPreviewImage, new Size(512, 512));
+
+ resizedPreviewImage.Save(newPreviewImageData, ImageFormat.Png);
+ previewImage.Pixbuf = new Gdk.Pixbuf(newPreviewImageData.ToArray());
+ }
+
+ Console.WriteLine("Updated preview image");
}
}
}
diff --git a/SpritePacker/SBRLUtilities/ResizeImage.cs b/SpritePacker/SBRLUtilities/ResizeImage.cs
new file mode 100644
index 0000000..2d1e08d
--- /dev/null
+++ b/SpritePacker/SBRLUtilities/ResizeImage.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+
+namespace SpritePacker.SBRLUtilities
+{
+ public static partial class ImageTools
+ {
+ ///
+ /// Resizes a Bitmap such that it fits within the target dimensions.
+ ///
+ /// The image to resize.
+ /// The target dimensions.
+ /// The resized image.
+ public static Bitmap ResizeImage(Bitmap sourceImage, Size targetBox)
+ {
+ float scaleFactor = Math.Min(
+ targetBox.Width / (float)sourceImage.Width,
+ targetBox.Height / (float)sourceImage.Height
+ );
+ Size thumbnailSize = new Size(
+ (int)(sourceImage.Width * scaleFactor),
+ (int)(sourceImage.Height * scaleFactor)
+ );
+
+ Bitmap resultImage = new Bitmap(thumbnailSize.Width, thumbnailSize.Height);
+
+ using (Graphics context = Graphics.FromImage(resultImage)) {
+ context.CompositingMode = CompositingMode.SourceCopy;
+ context.InterpolationMode = InterpolationMode.HighQualityBicubic;
+ context.DrawImage(sourceImage, new Rectangle(
+ Point.Empty,
+ thumbnailSize
+ ));
+ }
+
+ return resultImage;
+ }
+ }
+}
+
diff --git a/SpritePacker/SpritePacker.cs b/SpritePacker/SpritePacker.cs
index 661250a..9ae3da6 100644
--- a/SpritePacker/SpritePacker.cs
+++ b/SpritePacker/SpritePacker.cs
@@ -197,6 +197,7 @@ namespace SpritePacker
///
/// Generates an image that contains all the currently added sprites.
/// You probably want to call Arrage() before calling this method.
+ /// Returns null if you haven't added any sprites to the SpritePacker yet.
///
/// The generated image.
public Bitmap GenerateImage()
@@ -211,6 +212,9 @@ namespace SpritePacker
imageSize.X = spr.Right;
}
+ if (imageSize.IsEmpty)
+ return null;
+
Bitmap finalImage = new Bitmap(imageSize.X, imageSize.Y, PixelFormat.Format32bppArgb);
finalImage.MakeTransparent();
using (Graphics context = Graphics.FromImage(finalImage))
diff --git a/SpritePacker/SpritePacker.csproj b/SpritePacker/SpritePacker.csproj
index 3a29a08..02437c5 100644
--- a/SpritePacker/SpritePacker.csproj
+++ b/SpritePacker/SpritePacker.csproj
@@ -36,6 +36,10 @@
+
+
+
+
\ No newline at end of file