Source Code | Executable (Compiled for U.Va.'s blue.unix)
Here is the sample image I used to run all of these filters.

Note: while the program only deals with bitmaps, all files have been converted to JPEG for quicker loading of this page.
1. Noise: This filter adds random noise to the input image.
image -noise 0.3 < tree.bmp > noise.bmp
2. Brightness: Adjusts the brightness by the input factor through extrapolation and interpolation from black.
image -brightness 0.5 < tree.bmp > dim.bmp
image -brightness 1.5 < tree.bmp > dim.bmp
3. Contrast: Adjusts the contrast by the input factor through extrapolation and interpolation from an average gray tone calculated from the entire picture.
image -contrast 0.5 < tree.bmp > low_cont.bmp
image -contrast 1.5 < tree.bmp > high_cont.bmp
4. Saturation: Adjusts the saturation by the input factor through extrapolation and interpolation from a grayscale version of the image.
image -saturation 0.5 < tree.bmp > low_sat.bmp
image -saturation 1.5 < tree.bmp > high_sat.bmp
5. Crop: Makes a new image from a sub-selection. If the given sub-selection goes outside the range of the original image, black is substituted.
image -crop 50 50 200 200 < tree.bmp > cropped.bmp
6. Extract Channel: Extracts the given channel (1=red, 2=green, 3=blue) from the image.
image -extractChannel 1 < tree.bmp > red.bmp
image -extractChannel 2 < tree.bmp > green.bmp
image -extractChannel 3 < tree.bmp > blue.bmp
7. Quantize/Dither: Scales the image down to a given number of bits per channel. The quantize algorithm simply rounds the values to the nearest level, wheras the dithering algorithms attempt to spread the quantization errors around in such a way that the eye notices it less. The random dither is just that: the errors are tempered with random noise so the areas of a single color are broken up. The ordered dither (as used on the original Macintosh system) uses an experimentally determined matrix to spread the error. This results in a better image than the clumping which usually comes with random dithers, but it appears to be viewed through a screen. Floyd-Steinberg error diffusion spreads the quantization errors to neighboring pixels, again with experimentally determined proportions. This final method produces the best results, but is more computationally intensive.
image -quantize 3 < tree.bmp > quant.bmp
image -randomDither 3 < tree.bmp > random_dith.bmp
image -orderedDither 3 < tree.bmp > ordered_dith.bmp
image -FloydSteinbergDither 3 < tree.bmp > diffuse_dith.bmp
8. Blur/Sharpen: Blur uses a variable-width Gaussian sampling technique to take an average of the neighboring pixels at each sample. The sharpen algorithm merely reverses the process by first producing a blurred image, then extrapolating from it through the original.
image -blur 5 < tree.bmp > blur.bmp
image -sharpen 5 < tree.bmp > sharp.bmp
9. Edge Detect: The edge detect algorithm is simply a convolution with a 3x3 matrix which weights the central pixel positively and its neighbors negatively:
-1 | -1 | -1 |
-1 | 8 | -1 |
-1 | -1 | -1 |
image -edgeDetect < tree.bmp > edge.bmp
10. Scale: The scaling algorithm makes the image larger or smaller by the given factor.
x_orig = x * factor
y_orig = y * factor
The x_orig and y_orig are then fed to one of three sampling algorithms (since they are non-integer values and pixels are discrete quantities). The point sampling method merely rounds to the nearest pixel. The bilinear sampling takes an interpolation of the four nearest pixels to the sample point, and the Gaussian method uses a 3x3 discrete Gaussian approximation to take a weighted average of all neighboring pixels.
(These images extend beyond the border of my current layout because they're so danged big.)
image -sampling 0 -scale 2.0 2.0 < tree.bmp > point.bmp
image -sampling 1 -scale 2.0 2.0 < tree.bmp > bilinear.bmp
image -sampling 2 -scale 2.0 2.0 < tree.bmp > gauss.bmp
11. Rotate: The rotate algorithm spins the image around the center point by a given angle in degrees. The new image's pixels are obtained via the following algorithm:
x_orig = (x - x_center) * cos(theta) - (y - y_mid) * sin(theta)
y_orig = (x - x_center) * sin(theta) - (y - y_mid) * cos(theta)
These values are then fed to the sampling algorithm, which can again use any of the three methods outlined above. The version below uses point sampling.
image -rotate 45 < tree.bmp > rotate.bmp
12. Fun: I was told that this algorithm could do whatever I wanted it to do. I set it up to use the Unix program wget to fetch an image from my website, completely ignore the input image, and return this lovely bitmap, showing my graphics professor and TA in a bit of silly Photoshoppery. This particular "algorithm" no longer functions, as my webspace at U.Va. is now dead and I haven't bothered to recompile the program with a different image link. Alas, you'll just have to imagine.
image -fun < tree.bmp > fun.bmp
