- Index
- ImageMagick Examples Preface and Index
- Simple Distortions
- Rotate and Shearing
- Circular Warping
- Limiting the Warping with Regions
- Animations
(fun examples)
In this section we will look at general and simplier image warping and
distortion operators that are provided by ImageMagick. This is as a way of
wetting your appetite for the more advanced and complex distortions which we
will look at in later sections.
Simple Distortions
Simple distortions Operators just rearrange the pixels in the image. The
number of pixels and even the size of the image remains the same. The key
feature is that the image does not loose any information, it is just
rearranged, and could very easilly be returned to normal exactly as if no
processed has been done.
Basically it just rearranges the pixels, without destroying, overwriting,
copying, or color merging or modifying the conteants of the original image.
Flipping, and Mirroring
For these examples lets use this cute looking koala image...
The simplest image distortion is to rearrange the pixels in the
image so as to "-flip " it
upside-down.
convert koala.gif -flip flip.gif
| |
|
Or by using "-flop " you
can generate a mirror image.
convert koala.gif -flop flop.gif
| |
|
Transpose and Transverse, Diagonally
The "
-transpose
"
and "
-transverse
"
image operations produce diagonal mirrors of the image.
The "-transpose "
mirrors the image along the image top-left to bottom-right diagonal.
convert koala.gif -transpose transpose.gif
| |
|
While "-transverse "
mirrors the image along the image bottom-left to top-right diagonal.
convert koala.gif -transverse transverse.gif
| |
|
Rectangular Rotates
All the above operations, will essentially produce a mirror image of the
original. The "
-rotate
"
operator provides the other non-mirrored versions of the image, including the
original image itself.
convert koala.gif -rotate 0 rotate_0.gif
convert koala.gif -rotate 90 rotate_90.gif
convert koala.gif -rotate 180 rotate_180.gif
convert koala.gif -rotate -90 rotate-90.gif
convert koala.gif -rotate 360 rotate_360.gif
|
Note that "
-rotate
" is a
simple distort only if you use a rotation angle of a multiple of 90 degrees.
Any other angle will introduce other more complex pixel level distortions into
the image. See
Rotate below.
|
You may notice that a positive angle of rotation is clock-wise, which seems
to be logically incorrect. Internally however, it is mathematically
correct and is caused by use a of negated Y-axis. That is the Y-axis goes
from 0 at the top and positive downward. Because of this the coordinate
system in reversed, and thus rotation is also reversed mathematically.
|
Rolling Images like a bad TV
You can also "-roll " an
image horizontally (like a TV that is out of sync). The amount of the roll
(displacement of the image) is given in pixels.
convert koala.gif -roll +0+20 roll_horiz.gif
| |
|
Of course you can also roll the image sideways...
convert koala.gif -roll +30+0 roll_vert.gif
| |
|
Or by using a negative number of pixels, you can roll it in the opposite
direction.
convert koala.gif -roll +0-20 roll-horiz.gif
| |
|
Rolls are particularly important for
Tiled
Images as it repositions the tile origin, without destroying the images
'tilability'. In fact that is exactly what the "
-tile-offset
" setting
defines, how much roll to apply to a tiling image as it is read in by the "
-tile
" option.
Simple Rearrangements Summary
The most important aspect of all these operators is that you can add them all
together in many different ways such that the result will be
exactly as
if no operation was performed at all.
convert koala.gif -roll +25+0 -rotate 90 -flop \
-roll +0-25 -flip -rotate 90 original.gif
|
|
|
Rotating and Shearing
While the
Simple Distortion Operators (above) preserve
the images size and color, the next set does not. The results of these
operators do not fit in the original size, or even the original raster
grid of the image.
Rotating Images -- Simple Image Rotation
As you saw above the "
-rotate
" operator can perform simple, image preserving
distorts, when you rotate image in units of 90 degrees.
With other angles however, the rotated image will not fit nicely into a
rectangular image. Consequently to ensure that no image data is lost, the
size of the final image is enlarged just enough to accommodate the rotated
image.
convert koala.gif -rotate 30 rotate.jpg
|
|
|
Note that the direction of rotate is clock-wise. This may seem illogical
mathematically, until you realise that the image coordinate system is relative
to the top-left of the image instead of the mathematical norm of the
bottom-left. The result is the angle of rotation is the oppisite of what you
may logically expect. This is important to keep in mind when dealing with any
form of image rotation, compared to a mathematical rotation.
The extra space added by ImageMagick is colored with the current "-background " color
setting. Allowing you to specify the color to fill into the corners.
convert koala.gif -background lightblue -rotate 30 rotate_color.png
|
|
|
Of course if you want to fill with the transparent color, you will need to
ensure the image can handle transparency (by using a "-matte " operator to add an
alpha channel), and is saved to an image format that can handle transparency.
convert koala.gif -matte -background none -rotate 30 rotate_trans.png
|
|
|
If the extra space comes out black, then your output image output format does
not allow the use of an alpha channel, (most likely the JPEG format), so the
transparency defaults to black.
|
Before version 6.1.2, "-rotate " did not handle transparency correctly,
producing stripes of black and transparent in the corners of the rotated
image. The workaround for this problem was rather complex, involving
rotating the alpha channel separately to the colors.
|
But what if you don't what that extra space, wanting to preserve the images
original size? Well you can use a centered "
-crop
" to return the image to its original size.
If you don't know what the original size was, you can use an alpha composition
trick (see the
'Src
' Compose
Method) to restore the image back to its original size.
convert koala.gif -matte \( +clone -background none -rotate 30 \) \
-gravity center -compose Src -composite rotate_resized.png
|
|
|
The "
-rotate
" operator
also understands two extra flags. If a '
>
' symbol is added to
the rotate argument (before or after the number), then the image will only be
rotated if the image is wider than it is taller. The result is that this flag
will only rotate 'landscape' (wide) style images into 'portrait' (tall) style
images.
The other flag '
<
' does the opposite, only rotate images that
are taller than it is wide.
Digital photos can also be rotated to match the
Camera Orientation (based on the images EXIF meta-data) by using the "
-auto-orient
"
operator. However remember saving back to JPEG format may not be a good
idea.
Now for the bad news...
Because non-simple rotates are implemented as a sequence of
Shears there are some subsequent effects that result from.
First areas added into the image corners are just directly filled in using the
"
-background
" color.
You can not control this using
Virtual Pixel
Setting, as you normally would with more complex distortion techniques.
Also you can not control the mixing of colors during the
Image Rotation using the
Interpolation
Setting. Which means you can not preserve the original colors of the
image.
Rotating a Thin Line - rotation color blurring
For example here I rotated a simple vertical line of pixels by 17 degrees,
which I then scaled so as to show the effect of the individual pixels in the
resulting image.
convert -size 10x30 xc: -draw 'line 5,0 5,30' \
-background white -rotate 17 -scale 500% rotate_magnify.gif
| |
|
Note how the line seems to phase in and out in the rotated image, as it
crosses pixel boundaries. Not only that, but as rotate is implement using
multiple shears (see note above), the line only phased in sharply every second
pixel column. The the result is a line that is not only more blurry than it
needs to be, but has a gross 'beat' effect.
This 'rotation blur' is especially noticeable when you rotate small text and
labels, either attached to or part of a photo, by very small angles. Such
lines contain lots of fine detail that 'disappears' in a regular and highly
notice wave of blurring across the image.
The only direct solution to this problem is to use a Pixel Mapping technique, such as used by
the Scale-Rotate-Translate (SRT).
convert -size 10x30 xc: -draw 'line 5,0 5,30' \
-virtual-pixel white -filter point +distort SRT 17 \
-scale 500% rotate_SRT_magnify.gif
| |
|
Other variations of the above depend on the current
Interpolate Setting and can be see in
Interpolation of a Rotated Line. But as
you can see even default '
Bilinear
' interpolation setting will generally produce better
result that what was obtained using the original "
-rotate
" operator.
Also if you use the normal '-' version of the distort command, the
SRT distortion will automatically retain the
images original size, clipping the corners.
An alturnative method you can use when you don't have direct access to the
rotation operator (such as in when using the
Polaroid Transform, is to use the
Super Sampling technique (see below).
Basically we apply the operation to an image that is at least twice (or more)
the size of the final image size wanted. Afterward we then resize the image
to its final size so as to produce a very sharp and clean lines, edges, and
fonts.
For a more deeper understanding of the various image rotation algorithms and
the issues involved see
Leptonica Rotation.
Shearing Images -- Linear displacement
The "
-shear
" operator
takes each row (or column) of pixels and slides them along so that each row
(or column) is displaced by the same amount relative to the neighbouring row
(or column). Its two arguments are given in terms of angles.
Just as with "
-rotate
"
the operation increases the size of the resulting image so as not to loose any
information.
However shear is more complex in that it is really a double operation.
convert koala.gif -background Blue -shear 20 shear_rot.gif
convert koala.gif -background Blue -shear 20x0 shear_x.gif
convert koala.gif -background Blue -shear 0x50 shear_y.gif
convert koala.gif -background Blue -shear 20x50 shear_xy.gif
convert koala.gif -background Blue -shear 20x0 -shear 0x50 shear_xy2.gif
convert koala.gif -background Blue -shear 0x50 -shear 20x0 shear_yx.gif
|
If you look at the results you will see that the double form of the "
-shear
" operation is to do
the X shear first, followed by the Y shear (with an appropriate final image
size correction). This is fundamentally different to a Y shear followed by
the X shear, as in the last image.
If only one number is provided (without any '
x
') then "
-shear
" will apply it in
both the X and Y directions as a sort of poor mans rotate. For this reason
the units of shear are in degrees.
The "-background "
color setting is of course used as the color for the extra space added.
convert koala.gif -background none -shear 30 shear_trans.png
|
|
|
|
Before IM version 6.1.2 "-shear " did not handle transparency. The workaround for
for this problem was rather complex, involving shearing the alpha channel
separately to the colors.
|
Note that using a "
-shear
"
in this way is not a correct method for rotating an image.
To actually use shear to rotate an image properly, you would need to use a
need to perform multiple shearing operations in the form of
"-shear {X}x{Y} -shear {X}x0 -crop ...
", however
working out the proper values for the '
{X}
', '
{Y}
'
and final crop requires some trigonometry. The built-in "
Rotate Operator" (see above) is actually implemented in this way.
|
Note that shearing in the X direction will not affect an images height,
while shearing the the Y direction will not effect the images width. The
result is that the area covered by some object within the image will not
change (only the surrounding container holding the image).
|
Waving Images - Sine Wave Displacement
The "-wave " operator is
like "-shear " in that it
adds a 'linear displacement' to images. However this operator will only
displace columns of pixels vertically according to a sine wave function.
There are two arguments to the "-wave " operator. The first is the maximum height or
amplitude the pixels will be displace either up or down, while the
second is the wavelength of the sine function in pixels.
convert koala.gif -background Blue -wave 10x64 wave.jpg
|
|
|
Note that because pixels can be displaced up to the given amplitude,
that much extra space will always be added to both the top and bottom of the
image, even if that space is not actually needed.
For example by adjusting the arguments so that the wavelength is double
the width of the image, you can make the image into a arc.
convert koala.gif -background Blue -wave 20x150 arched.jpg
|
|
|
In this sort of case the unused space can be removed using either a "-chop ", "-shave ", or possibly even a
"-trim " operation.
Lets clean up the previous example by using a negative amplitude to flip the
arc over, and use "-chop "
to remove the unused space the "-wave " operator added.
convert koala.gif -background Blue -wave -20x150 \
-gravity South -chop 0x20 arched_2.jpg
|
|
|
Of course the "-background " color setting can be used to define the extra
space added to the image.
convert koala.gif -matte -background none -wave 10x75 wave_trans.png
|
|
|
As you can see from the above examples "-wave " only applies in the vertical or 'Y' direction. If
you want to add a wave in the X direction, you'll need to rotate the image
before and after you apply the wave.
convert koala.gif -rotate -90 -background Blue -wave -10x75 \
-rotate +90 wave_y.jpg
|
|
|
The technique can be used to add a wave pattern or vibration to an image at
any angle. Examples of this is given in the
Vibrato Font and in the
Smoking Font.
One other limitation with "
-wave
", is that the wave only starts at zero. That
is the left most column is not displaced, while the next few rows are
displaced downward (positive X direction), unless you give a negative
amplitude for an initial vertical offset.
Basically the "-wave "
operator does not (at this time) allow you to specify an offset for the start
of the sine function. This can be rectified however by adding, then removing,
an image offset using "-splice ".
convert koala.gif -splice 19x0+0+0 -background Blue -wave 10x75 \
-chop 19x0+0+0 wave_offset.jpg
|
|
|
While "
-wave
" will not make
use of the current
Virtual Pixel Setting
to define the color of the added areas, it will look at the current
Interpolation Setting to map the colors from
the source to the image generated. This means wave will tend to blur pixels
slightly in vertical bands across the image...
EXAMPLE: wave a image of horizontal lines.
However you can use a special
Super
Sampling technique to improve the blurring of the results.
EXAMPLE: supersampling of the previosu example
Circular Distortions
So far the image distortions have been rather mild, with very little
stretching, expanding or compressing of the image data. That is the data
remains pretty well unchanged.
These next few image operators can result in a image that is so distorted, the
original image can not be determined. The colors are twisted into a blurry
mess.
It also happens that they limit the distorting effects to a circular area with
little to no distortion of the original image at the edge of the image
rectangle. That means, you can use these operators on a small area or
Image Region and the result will still blend into the
original image without it looking like it was: cut out, warped and pasted back
into place.
That is they are limited 'local' distortion, which while generally applied to
the whole image, could be restricted to a smalled segment of the image. See
Region Limiting below.
Imploding Images
The "-implode "
operator warps the image so as to pull all the pixels toward the center. Its
sort of like sticking a vacuum, or 'black hole' in the center of the image and
sucking the pixels toward it.
Caution however is advised to only use very small values, to start with, and
slowly increase those values until you get the desired result. Most beginner
tend to use too large a value and get disappointed by the result.
For example this is a typical image implosion...
convert koala.gif -implode .6 implode.gif
|
|
|
Using increasingly larger values will essentially suck all the pixels in
the circle, into oblivion.
convert koala.gif -implode 5 implode_big.gif
|
|
|
However be warned that using any "
-implode
" value larger than '
1.0
' is also
effected by the
Virtual Pixel Setting,
as the algorithm starts to make color references beyond the boundaries of
actual image itself. As the default the "
-virtual-pixel
"
setting is 'edge', the edge color or surrounding frame on an image can have a
major effect on the result.
For example these two images are the same except one had white border added to
it. this basically shows the area which is using colors looked up from beyond
the bounds of the image proper. The area normally defined by the "
-virtual-pixel
"
setting.
convert rose: -gravity center -crop 46x46+0+0 +repage \
-implode 3 implode_rose.gif
convert rose: -gravity center -crop 44x44+0+0 +repage \
-bordercolor white -border 1 -implode 3 implode_rose_2.gif
|
|
|
Using different
Virtual Pixel settings such as
'
Background
' will produce the
same effect as adding "
-border
", but without enlarging the image.
Other
Virtual Pixel settings
can produce much more interesting effects in teh central imploded region.
For example using a '
Tile
' setting can add highly distorted copies of the image.
For example here I implode simple box image using this setting...
convert -size 94x94 xc:red -bordercolor white -border 3 \
-virtual-pixel tile -implode 4 implode_tiled_box.gif
|
|
|
More "
-virtual-pixel
" effects are explored on
Implosion Effects of Virtual Pixels.
As the number of pixels being imploded into a small area increases, and the
size of the implosion parameter gets very large, the results start to get a
'pixelated' look. To get a better more consistent result, you can increase
the number of pixels implode works with, using a technique called
Super-Sampling.
Basically by using a larger image (enlarging the source image if necessary),
doing the distortion, then shrinking the result to its final size you will
produce a much better result.
convert -size 94x94 xc:red -bordercolor white -border 3 \
-virtual-pixel tile -resize 400% -implode 4 -resize 25% \
implode_tiled_ss.gif
|
|
|
As you can see you get a much smoother and more realistic result that shows
the internal detail of the distortion much better. However even
super-sampling wil break down in extreme images like this, as it involved
infinities. If you look carefully you will see that a 'dotty' look returns,
but only closer into the center.
By using a larger "-border " around the image being imploded, and later removing
it again, you can also warp the edges of an image, inward toward the center.
convert koala.gif -bordercolor blue -border 20x20 \
-implode .5 -shave 18x18 implode_border.jpg
|
|
|
As of IM version 6.2.1 you can also use a transparent border, or image with
transparency...
convert koala.gif -bordercolor none -border 20x20 \
-implode .5 -shave 18x18 implode_border_trans.png
|
|
|
For other examples of imploded images see user
hh contributions
on Flickr.
Exploding Images
By using a negative value with the "-implode " operator, you can explode the image. This is
however more like magnifying the center of the image pushing all the
mid-radius pixels out toward the edge, rather than a true explosion.
convert koala.gif -implode -2 explode.jpg
|
|
|
Using larger value will essentially enlarge the center most pixels of the
image into a circle two-thirds the size of the smallest image dimension.
convert koala.gif -implode -30 explode_big.jpg
|
|
|
And here is a '
Super-Sampled', version.
convert koala.gif -resize 400% -implode -30 \
-resize 25% explode_big_ss.jpg
|
|
|
The central color of the internal 'explosion' is set by the color of the
center of the image (or region). This means that by changing the colors
around that point, before exploding your image, you can control the 'flash'
effect of the explosion. See
Animations below,
for an animated example of this color control.
Swirling Image Whirlpools
The "-swirl " operator
acts like a cake mixer. It will warp the image around in a circle the number
of degrees you give it as an argument.
convert koala.gif -swirl 180 swirl.jpg
|
|
|
By adding a border, and combining with "-implode " you can
give the look of a whirlpool sucking the image up to oblivion.
convert koala.gif -bordercolor white -border 20x20 \
-swirl 180 -implode .3 -shave 20x20 whirlpool.jpg
|
|
|
I have animated these swirling effects, which you can see below in
Animations.
Limiting the Distort with Regions
All of the distortion operators work on a full image. However some of the
distortion methods allow you to distort a smaller area or "
-region
".
For example here we have a line of stripes.
convert -size 600x70 xc:darkred \
-fill white -draw 'roundrectangle 5,5 595,65 5,5' \
-fill black -draw 'rectangle 5,25 595,31' \
-fill red -draw 'rectangle 5,39 595,45' \
lines.gif
|
Now by defining regions we can distort the line in various ways in specific
places.
convert lines.gif \
-region 90x70+10+0 -swirl 400 \
-region 90x70+100+0 -swirl 400 \
-region 90x70+190+0 -swirl -400 \
-region 120x70+280+0 -implode 1.5 \
-region 100x70+380+0 -implode -7 \
-region 101x90+480-10 -wave 10x50 \
lines_regions.gif
|
Note that the two
Circular Distortion operators "
-implode
" and "
-swirl
", fit into the use of
regions very well, as they have the property that the outside edge of the
distorted image matches up to the rest of the image outside the defined
region.
Also when I used the
Wave Distortion in the above, I had
to enlarge its defined "
-region
" of operation, beyond the bounds of the image
itself, so that it will work properly. This is very tricky, and may not be
practical in most image operations.
How Regions Work
In reality the way regions work is they basically extract area of the image
that the "
-region
"
covers. This image is then run through the distortion operator, and then it
is
Composed back on top of the original image.
This actually works for
any image operation (not just distorts).
For example here I define a region on the koala image, and
rotate it, with a 'blue' background 'corner fill'...
convert koala.gif -region 30x30+10+10 -background blue -rotate 30 \
koala_region_1.gif
| |
|
Even though this operation was not very useful in terms of results, you will
notice that only the defined region was modified.
The other thing that you should notice, is that as the resulting image was
enlarged by the rotation the enlarged image was still overlaid at the
original coordinates, overflowing the areas from which the image was
extracted.
The point this is that while regions can be used for interesting effects or
for limit the effect of operators, it will break down in its intended use if
the size of the extracted image is changed. That is you need to be careful in
what operations you apply to a extracted region.
Now what if instead of using a 'blue' corner fill, we instead use a
transparent fill.
convert koala.gif -region 30x30+10+10 -matte \
-background none -rotate 30 koala_region_2.gif
| |
|
This shows that when a region is overlaid back onto the original image,
anything that is transparent will show the original image. That is the
extracted region is only a copy, and does not erase the original area.
Finally you can do multiple operations on a region. For example...
convert koala.gif -region 30x30+10+10 -matte \
-background blue -rotate 30 -background red -rotate 30 \
koala_region_3.gif
| |
|
Note that the second 'red' rotation was applied to the previously 'blue'
rotated region extracted image. That is the modified region was not restored
to the original image until after both rotations had been applied.
In other words, the "
-region
" operator extracts an area of image to perform
operations in, and will only restore that area (using
Composite Over) when either the end of the
command is reached, or another "
-region
" is requested.
Animations (fun examples)
To finish off with lets generate some GIF animations of some of these
distorts. For these I generated some simple shells scripts to generate the
animated image, which you can also download and play with, using your own
test images.
This brings me to an important point. If generating a series of images using
these distorts, it is better to always distort from the original starting
image, rather than incrementally distort the image over-n-over.
This is especially true of rotated images where there is some blurring of the
result, though minimal in any individual operation, If you do it over an over
however, this is the results.
|
In the shell script "animate_mixer "
each frame is generated by using "-swirl " on the original image.
The swirl is animated in one direction, then back again to form a continuous
cycle. This is actually a very typical example animation in IM.
|
|
|
The shell script "animate_whirlpool ", not only uses "-swirl " on each image frame,
but also uses "-implode "
with an increasing argument size, as well.
I used a 'lightblue ' border color for the added space used to
show that the whole image will be 'sucked down the drain', though I should
have used the same white background color instead, for a better, more
realistic effect.
|
|
|
An explosion in the middle of the image (see script "animate_explode ". The image is again enlarged so the whole
image is exploded, and a colored dot is drawn at the center to define the
final color.
|
|
|
Using the shell script "animate_flex "
the center of the image is flexed up and down by changing the amplitude of the
"-wave " function both
positive and negative.
|
|
|
Using the shell script "animate_flag "
I create a 'offset wave' animation to make the image wave like a flag.
The animation can be improved by also vertically offsetting each frame of the
image so the left hand edge remains constant, and maybe adding a flag pole.
However that requires you to mathematically determine that offset, which can
be tricky.
|
|
|
The script "animate_rotate "
generated this rotating animation, but crops each frame with the original image
as described above to preserve the original image size.
|
|
Bonus Animations and Movies
As a bonus Florent Monnier from France created a neat video using the
"-swirl
" distortion
operator, made using a IM OCaml API script. Select the GIF animation to the
right to download the full version of the video. You can also have a look at
his notes about the video.
Can you make a good video demonstrating a distortion map technique? Do you
know of one elsewhere on the net? Mail me.
Created: 14 January 2009 (distorts sub-division)
Updated: 14 January 2009
Author: Anthony Thyssen,
<A.Thyssen@griffith.edu.au>
Examples Generated with:
URL: http://www.imagemagick.org/Usage/warping/