In preparation for a study group on Numeric Photography, I started toying with what language to use for the coding projects.
Feature shopping
My inclination, of course, was to go with Lisp. Part of the goal of the assignments, however, was to make interactive web applications for each assignment and a gallery at the end of the completed assignments. I experimented a bit with Armed Bear Common Lisp. The hurdles that I would need a user to go through to use my application safely were too great. The user would have to edit their own java.policy file to give my applet permission. If I wanted to let the user do that with a single click or something, I would have to spring for a $200/year code-signing cert.
My next choice then was stand-alone Lisp applications. Rather than online, interactive applications, I would have downloadable ones. Not ideal, but doable. The big hurdle here is crafting a GUI to run the application. The GUI wouldn’t be too terrible thanks to an interesting concept that Dirk Gerrits pointed out: Immediate Mode GUIs. I have already implemented the buttons from this tutorial in OpenGL under SBCL.
Late one night, I remembered Parenscript. It is a Lisp-like language that compiles to Javascript. Parenscript was a little bit more its own thing and a little bit less Lisp than I had wanted. But, it got me thinking. What can you do in Javascript these days?
I searched for image processing javascript. The first hit was Pixastic. It is a library of basic image processing functions that you can run on any image on your page. At its heart, it uses the Canvas element that is available on Safari, Firefox, and Opera. So, I figured, why not? If I can get an FFT working in Javascript, then there is nothing keeping me from implementing all of the assignments in Javascript. Yes, Javascript is awful, but it’s a dream compared to Java. The new Javascript debugging features in Safari are quite useful, too.
Success
Below is a simple example of what I have working. When you first load the page, you see an image of my son and my dad at the Pittsburgh Zoo. This image is actually loaded in a hidden image and copied into a visible canvas. You are seeing the canvas.
If you press the FFT
button and wait for it, you will see a representation of the 2-D Discrete Fourier Transform of the image. Really, the DFT output is complex numbers. The representation is just the magnitude of the complex numbers. The actual complex numbers are kept around in a variable so that when you hit the IFFT
button, it has enough information to actually reconstruct the image. So, the FFT
button works from the pixels in the canvas. The IFFT
button works from the data generated with the last FFT
. So, unfortunately, you cannot meaningfully FFT-FFT-IFFT-IFFT here. It is interesting, but not meaningful.
Also, I was trying to add a text box here so that you could use your own image, but I am not getting it right. You’re going to have to wait until I finish the whole assignment.
Clojure?
From everything I could find on Google, Clojure has the same issue Armed Bear has: It needs to instantiate its own ClassLoader. This causes a runtime permissions error unless it’s granted permissions by being signed and approved or being listed in the java.policy.
For canvas in IE, check out the all-javascript ExplorerCanvas:
http://excanvas.sourceforge.net/
It’s what I use at work (really reduced my IE special-cases, which in the case of my canvas usage would have been turbo-painful as it would have likely meant an entirely different code path for our entire annotation library on IE.
It can be slow depending on how crazy your canvas code is, but it does the job pretty reliably.
The Pixastic stuff definitely did some different things when the browser was IE. I should look to see if I can make it nice and cross-browser without too much headache.
I will check that out, thanks.
I’ve been playing about with graphics in javascript too – you might want to check out the new Worker stuff (works in firefox) which allows you to crunch numbers without killing the browser (your fft causes a few seconds lockup for me).
Oh, and firebug for debugging ftw.
it appears that it is not allowed to take cross domain canvas sources, this might help you out with your ‘assignment’ (allowing people to use their own images for the system)
http://forums.mozillazine.org/viewtopic.php?f=25&t=779915
Hmmm. I am loading the original image into an image that is in a collapsed div. Under Safari, at least, I can copy this into the canvas evenif the image is from off site. I do intend to allow users to select their own images.
Also, I think your link above to the Mozilla thread is broken.
[…] I posted a small script that lets you do Fast Fourier Transforms in Javascript. I did this in to test the waters to see if I could do the exercises for the Numeric Photography […]
I also found that opera and google chrome could work with off site images, but firefox wouldn’t do it. the thread I linked was called ‘.getImageData(…) not working in FF 3.0.1 for me’ and it says ‘It seems that firefox does not allow you to use getImageData(…) unless the source of the canvas is from the same domain, and it does not consider files on your hard drive as being from the same domain as an html document also on your hard drive.’
*nod*. The exact error line in the Firefox console is annoyingly ambiguous, but the behavior and appearance of the message totally fit. I can blit a foreign image to my local canvas, but thereafter I cannot read pixels from that canvas. And, yes… Sadly, both local files and “data:” URLs are considered to be on different sites than the “file:” document. *shrug*