Pipeline Image Sequence Editor
Pipeline.rb is an interface for manipulating single images, sequences of images, and frames dumped from video files, according to "plans" written in an intuitive, flexible domain-specific language.
To get Pipeline.rb running, first you must have Ruby.
If you already have ImageMagick installed, getting RMagick should be as simple as: gem install rmagick
Nevertheless, if you already have FFMpeg installed, you should be able to follow gwik's instructions to install ffmpeg-ruby at https://github.com/gwik/ffmpeg-ruby.
Tip: If you're like me, and couldn't figure out how to build FFMpeg to work with ffmpeg-ruby on OS X, try: ./configure --enable-shared --disable-static
Pipeline Image Sequence Editor <firstname.lastname@example.org> Usage: pipeline.rb [options] Example: pipeline.rb -p plan.p -i images/ Specific options: -i, --in-dir DIR Read input from DIR --stdin Read input for a single image via STDIN --in-vid PATH Read video using FFmpeg -o, --out-dir DIR Save output to DIR --out-vid PATH Save processed video as `filename' -I, --in-place Overwrite input files with output -p, --plan PLAN Process according to PLAN --plans x,y,z Process through a sequence of plans -h, --help Show this message -v, --verbose Verbose output --version Show version
Invert an entire directory of images and save the output to another directory: ./pipeline.rb -i input/ -p invert.p -o output/
Both of the following invert the inversion of an entire directory of images and save the output in-place:
./pipeline.rb -i input/ -p invert.p -p invert.p --in-place ./pipeline.rb --in-dir input/ --plans invert.p,invert.p -I
Invert every frame of a video file and dump the results to a directory: ./pipeline.rb --in-vid family.mov --plan invert.p --out-dir frames/
Both of the following process a single image via stdin:
cat gucci_mane.png | ./pipeline.rb --stdin -p invert.p >gucci_invert.png ./pipeline.rb --stdin -p invert.p <gucci_mane.png >gucci_invert.png
Plan File Syntax
Plans allow for two types of commands:
- Variable assignments, and
- Function calls
Both variable assignments and function calls take arguments of the following types:
- Predefined variables (i.e.
- External files (i.e.
- String (this is tentative...)
For example, a plan to swap the green and blue channels of an image, while inverting the red channel, takes the following form: splitRGB $1 invert $1 joinRGB $1 $3 $4
It is important to note that the numeric variables—
$2, etc.—are routinely overwritten by function calls within a plan. For example, had we wanted to apply ImageMagick's edge filter with a strength of 8 to an image, we would have written:
$red = $1
edge $3 8
joinRGB $red $2 $1
In the above example,
splitRGB saves the red channel of our input to
$1. We must store this before we call
edge on the blue channel (
$2), since the output of
edge will be stored in
$1. Finally we rejoin the channels. Note that the green channel (
$2) is unmodified.
Relying on the numbered variable system in the above examples grows cumbersome as the complexity of a plan file increases. Named variables circumvent this problem. Prior to this language feature, the following plan would have taken nearly 7 lines: $r, $g, $b = split_rgb $1 $mask = center_fit %(images/masks/big_willie_style.png) $r $r = multiply $mask $r join_rgb $r $g $b
Significantly, in the above example, only the final line modifies a numbered variable;
I am considering adopting a Ruby-esque syntax, wherein any function call with an exclamation mark modifies its first argument in-place. I.e., multiply! $red $mask would be the same as $red = multiply $red $mask