This is the second part of an ongoing series of articles that will hopefully shed some light on developing an Aperture Edit Plugin. This series is not meant to be a tutorial, but more of a documentation of my personal efforts to create a plugin for use in a two year long art project I will begin working on this fall. This art project is also going to be documented over at my website called Entropy Art. Please feel free to check it out, sign up and participate in any way that you would like. Also, I am making the source code for this plugin available as open source. As it is still just basically a template, I haven’t felt the need to choose a license for it yet, but I will eventually. For now, please feel free to download the code and contribute any ideas you would like.
In the last part of this series I went through the very basic steps of creating a new project in Xcode. At the end I included a script that will allow you to run Aperture in debug mode so that you can debug your plugin using Xcode’s built in tools. However I made a slight mistake in the script.
If you notice the destination paths in the script all refer to Plug-Ins/Export. This was copied over from a previous project I had been working on that was an Export plugin for Aperture. For an Edit plugin, this should be changed to “Edit.”
What Will My Plugin Do
At this point I want to achieve two things. I want to get my plugin to the point where it will load up my selected Aperture images and display them in the UI, and I want to really start thinking of what it is I want my plugin to do!
The first task was pretty easy as the SDK comes with a sample edit plugin that I was able to use to copy most of what I needed. It is pretty simple, and we will be going over it in this article.
The second task is a bit more involved. Of course, this will all evolve over time, but I sat down the other day and started to dream up what I would like my plugin to be. I also drew out some sketches of how I would like to UI to look and feel and I have included them here for all to see.
A professor of mine once told me that all good ideas can be drawn on a bar napkin ( or three ), so that is what I did.
After thinking about it for a while and making some notes I realized that what I really want is something akin to a few other applications out there. In fact, these other applications are really languages themselves, designed so that the people who use them can create scripts. But I want to make things a bit more visual. So, this plugin will do a number of important things. It will expose to the user a slew of image processing functions in a visual manner. They will be able to select for example a filter and use some controls to apply it to their image. Once they have their settings adjusted they will be able to add this “function” to a “script.” This script is essentially a list of the user’s selected functions and settings. You should be able to rearrange them in the order you want, and you should be able to edit them as needed.
You should also be able to save your scripts so that you can apply them to other images in the future. To start out I plan to draw on the various “Image Units” found in the Core Image library. These are pretty extensive and allow for quite a bit of modification. In addition that what is already available you can create your own image units via the OpenGL Shading Language.
I haven’t yet decided how I am going to present the data to the user if their function results in a 1D data-set ( images are 2D ). But I may have some view available that presents the data as a graph or something. For example, lets say the user wants to crunch their image into a histogram representation. I should be able to display things like histograms as well as 2D image data, but for now I will focus on 2D image data.
The other applications that I am sort of trying to mimic with this plugin are things like Processing or IDL/PV-Wave. They are full-on programming languages in their own right, but they basically do some of the things that I am trying to do here.
Building Blocks
To get things rolling I decided to tackle task number one and get my plugin to the point where it can load an image and display it to the user. This was actually really easy thanks to the SampleEditPlugin that comes packaged with the SDK.
My first step was to create a very simple user interface. This would essentially consist of a view for the image, next and previous buttons and done and cancel buttons. Using Interface builder I was able to set this up in no time simply by dragging the controls over from the library.
To do this, I opened the file in the template with the .nib extension. This is the user interface file and you edit it with an application called Interface Builder. It should open automatically in IB if you double click the file.

Once open you will see a few things. First of all there is the main window that houses all of your main UI elements. It already has a few items in it including the following: Application, First Responder, Files Owner, and an NSWindow simply called EditWindow.
The main pieces we will be interested in working with for the moment are the NSWindow and File’s Owner.
If it isn’t already opened by default, double click the EditWindow and you will see it appear. At the moment, there is nothing to it. It is just an empty NSWindow. Our first order of business is to get it to display on screen when we call the plugin from Aperture.
To do this we need to wire up the EditWindow to our outlet we have in code. To do this we control-click and drag from the item called File’s Owner to the EditWindow. You will see it highlighted when you are on it in blue. Once you release the mouse you will have a small drop-down box that asks you what you’d like to wire this to–select the only item in the list called _editWindow. This tells the plugin code that the outlet called _editWindow refers to that NSWindow in Interface Builder.
I’m really not exactly sure how this all works under the hood. It takes some getting used to and some reading up on Xcode really helps.
Once we have this wired up, we can run our plugin. If we select an image in Aperture and choose Edit With–>Visualize, we will see the single window appear. Unfortunately, we haven’t given our plugin a way to quit at this point, so we are forced to kill Aperture and the plugin by clicking Stop in Xcode.
So our next obvious task is to add in the four basic buttons. I start out by opening the file in Xcode called Visualize.h. This name will vary depending on the name of your plugin. This is our main controller class for the plugin and will do most of the work of controlling our UI, amongst other things.
In Visualize.h there are already a number of items added by the template. Let’s have a look.

As you can see in this screen shot the Aperture template has added a generic object called _apiManager, an NSObject called _editManager, and NSArray called _topLevelNibObjects, and our outlet for the NSWindow called _editWindow. Below this I have also added outlets for our four buttons and the NSView we will be implementing.
These outlets allow the code to manipulate the properties associated with each control. For example, if I want to enable or disable the Next and Previous buttons, I need to be able to access their properties programatically. These outlets make that connection in our UI.
In order to respond to an event ( when a user presses a button ) I need to add a few “actions.” At the bottom of the Visualize.h file, I add the following:
IBActions are the methods that get called when a user clicks a button or changes a slider’s value. These are the declarations for our button actions.

Once we have added this code we can jump back over to IB and wire things up. To wire up the IBOutlets we simply control-click and drag from File’s Owner to the button we wish to wire up. When the drop down appears you simply select the outlet that goes with the button in question. Oh, and I guess I forgot to mention that you need to add the four buttons to the NSWindow. Just drag them over from the library. You can also double click them to change the text from “Button” to whatever you want.
To wire up the actions, we basically do the opposite. Control-click and drag from the button to File’s Owner and select the appropriate action.
Once you have done this for all four buttons you will be able to write code to control what happens when a user presses the button, and you can manipulate your buttons properties in code.
At this point all I also want to add my view for the display of the image. To do this I am going to use an NSView which I drag over from the library. I also will wire this up to the NSView outlet I have created in Visualize.h called _imageView. I can stretch out the view to make it fill up most of the screen, and once I am done it looks something like the screenshot below.

Now I can save my interface and head back over to Xcode. The next step is to add the actual code that will get called whenever someone presses one of the four buttons I have placed in the UI.
Here is an example of what the code for the Cancel button looks like.

The action for the cancel button needs only one line of code at the moment. [_editManager cancelEditSession] simply tells the plugin to quit and to return things to the state they were in before opening the plugin.
For the remaining buttons I will leave the code empty for now. The Next and Previous buttons will require some more code that I still need to write, and the Done button actually does quite a bit as that is when all of the newly processed images get saved to disk.
But at least we can cancel our plugin at this point!
So at this point we still aren’t displaying any images. The plugin doesn’t know how to do this yet. In my next article we will go over how to get the plugin to display images, and how to implement the Next and Previous buttons. Hopefully by then I will have a clearer idea of what I want my plugin to do and how I want it to look! Until then, feel free to download the code and try it out for yourself. You may see some code that I haven’t gone over yet, as I tend to write these articles a little behind the actual coding progress, but hey, this way you get a heads up!
This entry was posted on Wednesday, August 20th, 2008 at 3:17 pm and is filed under Developers, Micah Walter. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.


