AutoMotivator has a
special fancy high
res version so you can, in theory, make a motivational poster
big enough
to print and hang
on your wall.
This has worked out reasonably well, but one sore point is the
performance of ImageMagick
for big images.
AutoMotivator works by taking the original photo, creating two PNGs
for the title and inspirational text, and compositing them together
against a black background
with convert. On
big images (2000 pixels or more on a side), it gets very slow
(5-20+ seconds) and sucks up a lot of memory.
I'm not sure why it's so slow, but I suspect it's loading all the
input images into memory, creating a big output image in memory,
filling in the output, and then writing the output to disk.
Since my compositing needs are pretty simple, I don't have to load
all that image data: producing each row of the output image only
requires reading one row from each the images that single output row
intersects. (This thought was originally inspired
by picturetile, which
must be incredibly slow.)
With that idea in mind, over the weekend I wrote a small
compositing program in C. It uses the row-at-a-time input and output
functions
from libpng
and libjpeg. The basic algorithm
is:
- get the dimensions and placement of the input data sources
- note which data sources appear on each row
- create a jpeg output object, and one output row
- for each row in the output:
- for each input source on that row:
- merge a row from the input into the output row
- write the output row out to disk
- finish the output jpeg
I'm really rusty at C (it's been over ten years since
my last useful C program),
but the end result is working well: my compositor is about ten times
faster than ImageMagick at assembling big poster images. Sure, it
also has a hundredth of the features, but it fortunately does
exactly what I need. And the difference in user experience quality between producing a poster
in two seconds and 20 seconds is huge.
|