Sign in to follow this  
Followers 0
MadDugan

Spritesheet Export Plugin

16 posts in this topic

7/24/2014 - v1.2.2 Minor Code change and recompile to support Paint.NET 4

 

I was in need of a consistent way to create simple, evenly spaced spritesheets from multiple layers in Paint.NET and I figured I would share the plugin.
 
DOWNLOAD: https://ssplugin.codeplex.com/releases/view/125730
 
This is a FileType plugin that will generate a PNG formatted file.
 
v1.2.1 -  Add honoring layer visibility.
v1.2.2  - Minor Code change and recompile to support Paint.NET 4

Installation Instructions

  • Verify Paint.NET is not running
  • Copy spritesheet.dll into the /Paint.NET/FileTypes sub-directory
  • Start Paint.NET and verify "SpriteSheet (*.ss.png)" is now an option for "Save as"

If there is a lot of interest, I will consider adding features, but as is, it suits my requirements.
 
Please cite if you use this tool for your application development and I will return the favor by linking to your application.
 
An example of multilayer sprite
post-102196-0-49478800-1364090376_thumb.
 
The resulting file created by exporter
post-102196-0-15765100-1364090385_thumb.

Edited by MadDugan
1

Share this post


Link to post
Share on other sites

Hi MadDugan - welcome to the forum :)

 

Your first plugin is very nicely done.  Works just as anticipated without hassle or fuss.  You've made a nice job of it.

 

You might want to mention in your post that it is a filetype plugin and the DLL should go in the /Filetypes/ folder.

0

Share this post


Link to post
Share on other sites

Hi MadDugan - welcome to the forum :)

 

Your first plugin is very nicely done.  Works just as anticipated without hassle or fuss.  You've made a nice job of it.

 

You might want to mention in your post that it is a filetype plugin and the DLL should go in the /Filetypes/ folder.

 

Thanks for the feedback.  I have made the changes as suggested.

0

Share this post


Link to post
Share on other sites

v1.2.1

Updated plugin to honor a layer's visibility flag

 

Scenerio where this would be used: Multiple sprite animations in one file for proper centering and resizing then only making visible layers you want to export.

0

Share this post


Link to post
Share on other sites

v1.2.1

Updated plugin to honor a layer's visibility flag

 

Scenerio where this would be used: Multiple sprite animations in one file for proper centering and resizing then only making visible layers you want to export.

I haven't used either of those, but I highly recommend this one.

0

Share this post


Link to post
Share on other sites

DennisW mentioned in the ImPDF thread that the SpriteSheet Export plugin is not working. I verfied this and he is right.

 

Maybe a moderator could mark the first post in the thread with 'Not Paint.NET 4 compatible'.

System.TypeLoadException: Could not load type 'PaintDotNet.GdiPlusFileType' from assembly 'PaintDotNet.Data, Version=4.2.5309.33059, Culture=neutral, PublicKeyToken=null'.

   at SpriteSheet.MyFileType.OnSave(Document input, Stream output, SaveConfigToken token, Surface scratchSurface, ProgressEventHandler callback)

   at PaintDotNet.FileType.Save(Document input, Stream output, SaveConfigToken token, Surface scratchSurface, ProgressEventHandler callback, Boolean rememberToken) in d:\src\pdn\paintdotnet\src\Data\FileType.cs:line 284

   at PaintDotNet.Controls.DocumentWorkspace.<>c__DisplayClass30.<DoSave>b__28() in d:\src\pdn\paintdotnet\src\PaintDotNet\Controls\DocumentWorkspace.cs:line 2953

   at PaintDotNet.Functional.Func.Try(Action f) in d:\src\pdn\paintdotnet\src\Base\Functional\Func.cs:line 171
0

Share this post


Link to post
Share on other sites

I'll  get on to this later today.

 

I have a handful of plugins to check - SpriteSheet Export has been added to the list.

0

Share this post


Link to post
Share on other sites

Looks like BB already did the dirty work.

0

Share this post


Link to post
Share on other sites

It would be great to see the problem with this plugin resolved. So it can work in V 4.02

0

Share this post


Link to post
Share on other sites

This might help.

 

Hidden Content:
0

Share this post


Link to post
Share on other sites

This might help.

 

Hidden Content:
/////////////////////////////////////////////////////////////////////////////////
// paint.net                                                                   //
// Copyright (C) dotPDN LLC, Rick Brewster, and contributors.                  //
// All Rights Reserved.                                                        //
/////////////////////////////////////////////////////////////////////////////////
 
using PaintDotNet.SystemLayer;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
 
namespace PaintDotNet.Data
{
    /// <summary>
    /// Implements FileType for generic GDI+ codecs.
    /// </summary>
    /// <remarks>
    /// GDI+ file types do not support custom headers.
    /// </remarks>
    internal class GdiPlusFileType
        : FileType
    {
        private ImageFormat imageFormat; 
        public ImageFormat ImageFormat
        {
            get
            {
                return this.imageFormat;
            }
        }
 
        protected override void OnSave(Document input, Stream output, SaveConfigToken token, Surface scratchSurface, ProgressEventHandler callback)
        {
            GdiPlusFileType.Save(input, output, scratchSurface, this.ImageFormat, callback);
        }
 
        public static void Save(Document input, Stream output, Surface scratchSurface, ImageFormat format, ProgressEventHandler callback)
        {
            // flatten the document
            scratchSurface.Clear(ColorBgra.FromBgra(0, 0, 0, 0));
 
            using (RenderArgs ra = new RenderArgs(scratchSurface))
            {
                input.Render(ra, true);
            }
 
            using (Bitmap bitmap = scratchSurface.CreateAliasedBitmap())
            {
                LoadProperties(bitmap, input);
                bitmap.Save(output, format);
            }
        }
 
        public static void LoadProperties(Image dstImage, Document srcDoc)
        {
            LoadProperties(dstImage, srcDoc, _ => true);
        }
 
        public static void LoadProperties(Image dstImage, Document srcDoc, Func<PropertyItem, bool> selectorFn)
        {
            Bitmap asBitmap = dstImage as Bitmap;
 
            if (asBitmap != null)
            {
                // Sometimes GDI+ does not honor the resolution tags that we
                // put in manually via the EXIF properties.
                float dpiX;
                float dpiY;
 
                switch (srcDoc.DpuUnit)
                {
                    case MeasurementUnit.Centimeter:
                        dpiX = (float)Document.DotsPerCmToDotsPerInch(srcDoc.DpuX);
                        dpiY = (float)Document.DotsPerCmToDotsPerInch(srcDoc.DpuY);
                        break;
 
                    case MeasurementUnit.Inch:
                        dpiX = (float)srcDoc.DpuX;
                        dpiY = (float)srcDoc.DpuY;
                        break;
 
                    default:
                    case MeasurementUnit.Pixel:
                        dpiX = 1.0f;
                        dpiY = 1.0f;
                        break;
                }
 
                try
                {
                    asBitmap.SetResolution(dpiX, dpiY);
                }
 
                catch (Exception)
                {
                    // Ignore error
                }
            }
 
            Metadata metaData = srcDoc.Metadata;
 
            foreach (string key in metaData.GetKeys(Metadata.ExifSectionName))
            {
                string blob = metaData.GetValue(Metadata.ExifSectionName, key);
                PropertyItem pi = PdnGraphics.DeserializePropertyItem(blob);
 
                bool include = selectorFn(pi);
 
                if (include)
                {
                    try
                    {
                        dstImage.SetPropertyItem(pi);
                    }
 
                    catch (ArgumentException)
                    {
                        // Ignore error: the image does not support property items
                    }
                }
            }
        }
 
        protected override Document OnLoad(Stream input)
        {
            using (Image image = Image.FromStream(input, false, true))
            {
                Document document = Document.FromGdipImage(image, false);
                return document;
            }
        }
        
        public static ImageCodecInfo GetImageCodecInfo(ImageFormat format)
        {
            ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
 
            foreach (ImageCodecInfo icf in encoders)
            {
                if (icf.FormatID == format.Guid)
                {
                    return icf;
                }
            }
 
            return null;
        }
 
        public GdiPlusFileType(string name, ImageFormat imageFormat, bool supportsLayers, string[] extensions)
            : this(name, imageFormat, supportsLayers, extensions, false)
        {
        }
 
        public GdiPlusFileType(string name, ImageFormat imageFormat, bool supportsLayers, string[] extensions, bool savesWithProgress)
            : base(name, 
                   (supportsLayers ? FileTypeFlags.SupportsLayers : 0) | 
                       FileTypeFlags.SupportsLoading | 
                       FileTypeFlags.SupportsSaving | 
                       (savesWithProgress ? FileTypeFlags.SavesWithProgress : 0),
                   extensions)
        {
            this.imageFormat = imageFormat;
        }
    }
}

Exactly what I needed. Thanks!

0

Share this post


Link to post
Share on other sites

I tried to use the new version 1.22 and I get this error

 

System.TypeLoadException: Could not load type 'PaintDotNet.GdiPlusFileType' from assembly 'PaintDotNet.Data, Version=4.3.5316.40022, Culture=neutral, PublicKeyToken=null'.

   at SpriteSheet.MyFileType.OnSave(Document input, Stream output, SaveConfigToken token, Surface scratchSurface, ProgressEventHandler callback)

   at PaintDotNet.FileType.Save(Document input, Stream output, SaveConfigToken token, Surface scratchSurface, ProgressEventHandler callback, Boolean rememberToken) in d:\src\pdn\paintdotnet\src\Data\FileType.cs:line 284

   at PaintDotNet.Controls.DocumentWorkspace.<>c__DisplayClass30.<DoSave>b__28() in d:\src\pdn\paintdotnet\src\PaintDotNet\Controls\DocumentWorkspace.cs:line 2954

   at PaintDotNet.Functional.Func.Try(Action f) in d:\src\pdn\paintdotnet\src\Base\Functional\Func.cs:line 174

 

My apologizes I checked things over and I found that the dll was not installed in the correct place. I corrected the install and low and behold it worked. Please forgive my error Great work nice to have it back again.
 
Dennis 
Edited by DennisW
0

Share this post


Link to post
Share on other sites

 

I tried to use the new version 1.22 and I get this error

System.TypeLoadException: Could not load type 'PaintDotNet.GdiPlusFileType' from assembly 'PaintDotNet.Data, Version=4.3.5316.40022, Culture=neutral, PublicKeyToken=null'.
   at SpriteSheet.MyFileType.OnSave(Document input, Stream output, SaveConfigToken token, Surface scratchSurface, ProgressEventHandler callback)
   at PaintDotNet.FileType.Save(Document input, Stream output, SaveConfigToken token, Surface scratchSurface, ProgressEventHandler callback, Boolean rememberToken) in d:\src\pdn\paintdotnet\src\Data\FileType.cs:line 284
   at PaintDotNet.Controls.DocumentWorkspace.<>c__DisplayClass30.<DoSave>b__28() in d:\src\pdn\paintdotnet\src\PaintDotNet\Controls\DocumentWorkspace.cs:line 2954
   at PaintDotNet.Functional.Func.Try(Action f) in d:\src\pdn\paintdotnet\src\Base\Functional\Func.cs:line 174
My apologizes I checked things over and I found that the dll was not installed in the correct place. I corrected the install and low and behold it worked. Please forgive my error Great work nice to have it back again.
 
Dennis 

 

 

I got notified before your edit and immediately thought maybe it was still finding 1.2.1 somewhere.  Glad to see you resolved it.

 

-M

0

Share this post


Link to post
Share on other sites
Thanks for the plug. 

Can make a plugin to save each layer in the file? 

Such exists, but the new version does not work.

0

Share this post


Link to post
Share on other sites

You mean LayerSaver?  If there's a problem with it, post your question in the layersaver thread.

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0