Importing image sequences

Project Page Next project post Post History

Since the last posting, I've been starting to work on the lens calibration engine interface. However, I ran into a small issue: I wasn't able to import images as clips. Now, for the lens calibration, I don't necessarily need an image sequence, but I do need a clip that houses an image.

The first thing I did was to add in the capability of adding an image as a project clip. I then had this idea that, if in future, I was able to use my software on camera footage I can't currently import, that maybe I could import an image sequence. So I continued to extend the project library structure so that it would support an image sequence a clip. Turns out, in Cinema4D, this isn't entirely straight forward to do.

You see, when a file is drag and dropped into Cinema4D, it runs through each file individually and sends out a message for the individual file to be processed. This is then repeated for each of the next files. Wouldn't you have thought they'd allow the option to catch the array of files before needing to process them individually?

I'm a little surprised they didn't account for this. Anyway...

I really felt I needed to support image sequences though. So to do this, I had to add quite a bit of additional support code and functionality to a few areas of the program. Let's begin...

I had to update the drag and drop code handling to support image files. Then I had to update the dialog's timer function, which until now was used exclusively for the interface animations. The timer now includes file queue checks. This wasn't all smooth sailing, the timer runs in it's own thread. This posed it's own problem, because now I have to send out an additional core message to call the queue import dialog window from the main thread. It's never straight forward, is it?

Then there's the progress dialog itself. It's just a simple dialog with a progress bar. But even this is not straight forward, because the dialog's process function runs on another thread too! So now there's another thread to deal with. Here's what the little progress dialog window looks like:

The little import progress dialog

How I make an image sequence clip is by testing the import to see if there's a match to another image clip. This required additional code in the project clip functions. I also needed to include a sorting function, to sort out the image sequence by their frame number. This required a bunch of string operations to grab the frame number from the file name. I needed to do this because the selected file array doesn't always start where you want it to.

In addition to this, there's also the functionality to extend the current project's length, if the image sequence expands. I also added in the ability to set the project's length in the project settings layout, which I hadn't put there when I originally made it. So, you can now change the project's length in the project settings layout as well.

Then there's updating the viewport. Because the progress dialog runs on another thread, I had to send out another message once the import was finished via the core message system, so that the viewport updating ran on the main thread.

So, what was the big issue with all this. Well, the biggest issue was when I add a clip to a project, the viewport get's updated. The issue? If each of the files are imported individually by Cinema4D, then I have to do expensive redraws each time a file is added. Imagine doin this for an image sequence that's thousands of files long. This could have been quite painful. Deferring all the imports into a queue solved this, but made it much more complex to deal with because the queued import and the way it all works runs in a threaded environment, which has it' sown complexities.

As I said earlier, it's never straight forward, is it.

I don't know if I've covered this very well, but all in all, it has taken quite the figuring out. Particularly where two of the three main operations related to all of this happen in their own thread. But, there's a system in place now - and it appears to work. Here's a screen cap of the clip print out:

A print showing the image sequence with 6 frames. This layout by the way, I made to print various program information, mostly for debugging purposes.

Those with a keen eye will spot that there's still a few bugs to iron out. But, it shows the new image sequence support.

During all this, I also added the functionality to:

  • export a video clip into an image sequence. Not quite sure what the need for this is yet, but I think it's useful nonetheless. I could for example, work with a proxy image sequence instead of the raw video file. This function uses it's own progress dialog to show export progression.
  • Added in the beginnings of The Dark Room preferences container, which gets saved with Cinema4D. This means I can save user settings that can be loaded when Cinema4D starts up.
  • Added in the ability to use special characters in strings and text. Not a major thing, but it just allows me to use some characters that might be useful, such as the tick icon (there's an example of this in the image below!).
  • Added in a release notes room to the main dialog layout. This is mostly for my own benefit to show what's been done and what's still to do. It's just a high-level checklist of where I'm at. The release room looks like this:
The release room, a helper layout to list what I've done and what's to come. The image also shows the special tick characters, which I can now support in strings and text.

I mentioned at the start of the thread, that the lens calibration doesn't need image sequences. So why the work for all of this? Well, while I was extending the clip containers to support images, I had this thought that maybe, one day in the future, if I'm ever needing to do some sort of tracking on a video file my software can't read (maybe from a potential client!?), I have the option to import an image sequence instead. So, now I can import an image sequence and use it as a clip, which means I can just about import anything and work on it in some way. Cool bananas.

And to think that all this started because I wanted to import a single image for the lens calibration engine.

Now that the above has been implemented, it's back to programming the lens calibration interface...!