This content has moved - please find it at https://blog.cyotek.com.

Although these pages remain accessible, some content may not display correctly in future as the new blog evolves.

Visit https://blog.cyotek.com.

Gif Animator and Image Effects

Although we haven't really drawn attention to it by providing samples or SDK documentation, all of Cyotek's products are extensible in various ways. As long as you can code in a .NET language and can work with the API each product provides that is.

Cyotek's Gif Animator is no exception. The currently released version supports the same level of "standard" add-ins that other products include, and the development version now includes a new experimental image effects plugin system too.

Applying an effect to multiple animation frames

When it came to adding support for custom image effects, I wanted to simplify the process of how to create them as typically extension development isn't the most intuitive of tasks. In additional, I was originally going to directly reuse the effects library that Spriter uses, but that's not really possible.

Behind the scenes, Spriter's image processing is a little clunky - it passes Bitmaps and Images around and expects effects to return the same information. That doesn't make for the fastest of processing, even though Spriter does try to mitigate this in small ways.

Gif Animator on the other hand, works purely with the description of an image. For an optimized frame, this is a flat array of bytes pointing to entries in an 8bit palette. An unoptimized frame uses a flat array of 32bit ARGB colours. Image processing is therefore much faster and there's no need to create images at each turn - only when you actually want to display an image on the screen.

Part of the problem is also writing effects. Ideally, effects should essentially be macro's which take a colour and do something with it. Why make it horribly complex?

I currently use Paint.NET for most of our image editing, and that has an extensive plugin scene. BoltBait provides a handy overview on how Paint.NET does it's processing and more importantly provides CodeLab, a tool which takes a portion of user code and converts it into a full effect, without the user having to worry about development environments, references or any number of things. I thought it worked really well, so I reused the idea's for Gif Animator.

The screenshot below shows an example of the new Effect Builder extension for Gif Animator:

An example effect that inverts the colours of an image

Not quite macro status (at the moment you still need to generate a DLL, although this tool will do it for you) but much better than Spriter's solution, plus it's WYSIWYG - much easier for testing. I wonder why I didn't think of this myself.

The effects API is also somewhat derived from Paint.NET's - I had a look at the older source code from when it was made available and I've borrowed some idea's from that too. I thought the technique I am using in Gif Animator for image processing was fast (essentially I use pointers when I actually want to create a true bitmap or for deconstructing an existing bitmap and the rest of the time it's just accessing values in an array), but Paint.NET is doing something beyond that. At some point I'll spend some more time with that code and see if there's some new tricks for me to learn, but the code I've previously written is more than suitable for the task.

One thing I'm not doing yet is multi-threading effects. I think I have a peculiar blind spot when it comes to that. I'll happily use asynchronous, background, or multi-threaded tasks to keep a UI responsive, but I never seem to consider using it to break up execution of a single task. Off the top of my head I can only think of one place I do that, and that is the directory scanning parts of CopyTools. So with that said, these effects won't be threaded at the current time, although given that animations are typically fairly small I don't think this will be a problem. The effects API is designed to be quite generic for use with Gif Animator and any new products of a similar nature, and I intend to update Spriter to use this too - although given how Spriter works this may have be a "version next" feature.

Originally I only planned to obtain implementation ideas from the CodeLab plugin, but in the end I used a lot of code from it too, specifically in regards to the syntax highlighting and intellisense. Normally I would use our customized version of the DigitalRune Text Editor Control but I wasn't happy with the extreme flicking I was getting when testing intellisense, so I went with CodeLab's rich text version - it's not without it's own flaws, but no crazy flicker. As a result of this, I'll make the source code available for the Effects Builder with the next update release and then look later at sorting out the normal editor.

As for when the next release will be, at the moment I'm not sure. Currently the effects extension doesn't support any form of configuration UI which is fairly important for anything other than the most basic of transforms, so unless any bugs are found that ought to be fixed sooner rather than later I may delay the release to work in the effects API some more.

Update History

  • 2014-04-06 - First published
  • 2020-11-23 - Updated formatting

Leave a Comment

While we appreciate comments from our users, please follow our posting guidelines. Have you tried the Cyotek Forums for support from Cyotek and the community?

Styling with Markdown is supported