Inspired by `jq`, iq is an experimental tool for manipulating images through expressions which transform pixels.
iq 0.1.0
michaelgiba@gmail.com
USAGE:
iq [OPTIONS] [ARGS]
ARGS:
<input_path> The path to the input image
<output_path> Where to write the output image
OPTIONS:
-b, --blank <dimensions> Use a blank canvas of provided size 'HxW' (ex. '100x300')
-e, --expr <expressions> The expressions to evaluate
-f, --file <file> Pass a file containing expressions to run
-h, --help Print help information
-V, --version Print version information
Disclaimer: The tool is a work in progress and in its very early stages. There are certainly bugs and plenty of things to improve.
iq
is passed an image and a set of expressions and produces an output image. For example:
iq -e "_ => p(_.y, _.x, _.r, 0, 0)" assets/dalle_logo.png out.jpg
Would produce an output image out.jpg
with the green and blue color channels removed.
Expressions can do much more complex actions than simply uniformly changing colors. For example given this DALLE generated image of Philip Seymour Hoffman in the Disney film "Cars":
We can crop patches of the image using "slice ranges":
# Crop out a circle and replace the outside with a gradient
iq -e "[0:100, 0:100]" \
assets/examples/dalle_philip_seymour_in_cars_movie.jpg \
cropped_seymour.jpg
We can use match expressions to apply other expressions conditionally
# Change any pixel with a green channel value greater than 128 to white
iq -e "_.g > 128 => p(_.y, _.x, 255, 255, 255) : _" \
assets/examples/dalle_philip_seymour_in_cars_movie.jpg \
highlight_mcqueen.jpg
# Crop out a circle and replace the outside with a gradient
iq -e "
([].w/2) >= sqrt(sq(_.x - center().x) + sq(_.y - center().y)) =>
p(_.y, _.x, _.r, 255 - _.r, _.r) :
p(_.y, _.x, (_.r * _.y) / [].h, (_.g * _.x) / [].w, 0)
" \
assets/examples/dalle_philip_seymour_in_cars_movie.jpg \
circle_seymour.jpg
If we provide more than one expression separated by semicolons they will be alpha composited together. For example consider this DALLE generated bottle of ranch testifying in court;
# Superimpose a rotated version on the original;
iq -e "
_ => p(_.y, _.x, _.r, _.g, _.b, _.a * 0.5);
_ => p(_.x, _.y, _.r, _.g, _.b, _.a * 0.5);
" \
assets/examples/dalle_ranch_testifying_in_court.jpg \
rotate.jpg
There are a few builtin pixel functions like:
color_norm
color_add
color_scale
neighbors
That when combined with other standard features can even do some convolutions like this sobel edge detection:
# Crop into a circle and do sobel edge detection
iq -e "
([].w/2) >= sqrt(sq(_.x - center().x) + sq(_.y - center().y)) => color_norm(color_add(
color_scale(neighbors(_, -1, -1), -1.0),
color_scale(neighbors(_, 0, -1), -2.0),
color_scale(neighbors(_, 1, -1), -1.0),
color_scale(neighbors(_, 1, -1), 1.0),
color_scale(neighbors(_, 1, 0), 2.0),
color_scale(neighbors(_, 1, 1), 1.0)
));
" \
assets/examples/dalle_ranch_testifying_in_court.jpg \
circle_edge_ranch.jpg
Coming soon...
iq
is written in rust
and uses LALRPOP for parser/lexer generation.
Right now the tool is only distributed as source. Clone the repo and do a standard cargo build
All contributions are welcome!
Distributed under the MIT License. See LICENSE.txt
for more information.