Fred's ImageMagick Scripts



    Licensing:

    My scripts are available free of charge for non-commercial use, ONLY.

    For use of my scripts in commercial (for-profit) environments or non-free applications, please contact me (Fred Weinhaus) for licensing arrangements. My email address is fmw at alink dot net.

    If you: 1) redistribute, 2) incorporate any of these scripts into other free applications or 3) reprogram them in another scripting language, then you must contact me for permission, especially if the result might be used in a commercial or for-profit environment.

    Usage, whether stated in the script or not, is restricted to the above licensing arrangements. It is also subject to the ImageMagick license, which can be found at: http://www.imagemagick.org/script/license.php

CYLINDERIZE


Applies a cylinder distortion to an image so that the image is wrapped about the cylinder

Download Script

last modified: September 01, 2013



USAGE: cylinderize [-m mode] [-r radius] [-l length] [-w wrap] [-f fcolor] [-a angle] [-p pitch] [-n narrow] [e efactor] [-s scale] [-o offset] [-v vpmethod] [-b bgcolor] [-t] infile [bgfile] outfile
USAGE: cylinderize [-h or -help]

-m .... mode ......... mode of orientation for cylinder axis; options are
...................... horizontal (or h) or vertical (or v); default=horizontal
-r .... radius ....... radius of cylinder; float>0; default is one quarter
...................... of image width or height depending upon mode.
-l .... length ....... length of cylinder; lenght>0; default=width or height
...................... depending upon mode and adjusted for the cylinder pitch angle.
-w .... wrap ......... percentage of image to wrap about the cylinder; float;
...................... 10<=wrap<=100; default=50
-f .... fcolor ....... fill color for portion of cylinder not covered by the
...................... image; default=none (transparent)
-a .... angle ........ rotation angle in degrees about cylinder axis;
...................... best used when wrap=full; float; -360<=angle<=360;
...................... default=0
-p .... pitch ........ pitch (tilt) angle of cylinder; float; -90<pitch<90;
...................... default=0
-n .... narrow ....... narrow is the percent ratio of the bottom-to-top or
...................... right-to-left radii used to simulate perspective tapering;
...................... floats>=0; default=100 means same size radii
-e .... efactor ...... exaggeration factor for pitch curvature of the bottom of
...................... the cylinder to make perspective views more realistic;
...................... float>=1; default=1 i.e. no exaggeration. Nominal is 2.
-s .... scale ........ percent scaling of the infile in either the vertical or
...................... horizontal dimension as appropriate to the mode;
...................... integer>=100; default=100
-o .... offsets ...... x and y offset pair in the following form: +-Xoff+-Yoff;
...................... where either the + or - sign is required; values are
...................... integers; default=+0+0
-v .... vpmethod ..... virtual-pixel method; default=black
-b .... bgcolor ...... background color for the case when vpmethod=background;
...................... default=black
-t ................... trim background

bgfile is an optional background file onto which the cylinderized infile is
to be composited at the offset coordinated relative to the center of the bgfile

PURPOSE: To apply a cylinder distortion to an image.

DESCRIPTION: CYLINDERIZE applies a cylinder distortion to an image so that the image is wrapped about the cylinder. The image can be wrapped about any percentage of the cylinder from 10 to 100 percent. If the wrap is less than 100%, then the cylinder will be colored to fill the remaining amount. The cylinder can also be pitched (tilted).

ARGUMENTS:

-m mode ... MODE specifies the orientation for the cylinder axis. The choices are horizontal (or h) or vertical (or v). The default is horizontal.

-r radius ... RADIUS is the radius of the cylinder in pixels. The values are floats>0. The default is one quarter of the image width or height depending upon the mode.

-l length ... Length is the length of the cylinder along its axis in pixels. The values are floats with length>0. The default is either the width or height depending upon mode and adjusted for the pitch of the cylinder. If a length is provided, then the cylinder length will not be adjusted for pitch, but the ends will still be adjusted for pitch.

-w wrap ... WRAP is the percentage of the cylinder circumference that is wrapped with the image. Values are floats such that 10<=wrap<=100. Default=50.

-f fcolor ... FCOLOR is the fill color to put on the remainder of the cylinder that is not covered by the image. Any valid IM color is allowed. The default is none (for transparent).

-a angle ... ANGLE is the rotation of the image about the cylinder. This is best used when wrap=full. The values are floats with -360<=angle<=360. The default=0.

-p pitch ... PITCH (tilt) angle of the cylinder. Values are floats with -90<pitch<90. Positive values move the top or left side towards the user depending upon mode. The default=0.

-n narrow ... NARROW is the percent ratio of the bottom-to-top or right-to-left radii used to simulate perspective tapering. Values are floats>=0. The default=100 means same size radii.

-e efactor ... EFACTOR is the exaggeration factor for the pitch curvature of the bottom of the cylinder in order to make perspective views more realistic. Values are floats>=1. The default=1 i.e. no exaggeration. From my limited tests a value of 2 works well for pitch values up to at least 20 degrees.

-s scale ... SCALE is the percent scaling of the infile in the vertical or horizontal dimension as appropriate to the mode. Values are integer>=100; The default=100. This can be used to compensate for the distortions introduced by the top and bottom curvatures.

-o offsets ... OFFSETS are the x and y offset pair in the following form: +-Xoff+-Yoff (no spaces) where either the + or - sign is required. Numerical values are integers. The default=+0+0. The offsets are used to position the cylinderized image over the background image relative to its center.

-b bgcolor ... BGCOLOR is the background color to use when vpmethod=background. Any valid IM color is allowed. The background will be transparent if bgcolor=none and vpmethod=background. The default is black.

-t ... TRIM the background.

NOTE: Problems occur when the input image is smaller than the radius. To mitigate this, pad the input image with transparency so that the appropriate dimension is larger than the radius. Set the length to the unpadded dimension of the image and lower the -w argument value. and lower the -w argument value. See Overlay Example 4 below.

NOTE: Thanks to Anthony Thyssen for the concept and basic equation for achieving the tilted cylinder effect. Thanks to Glen Fiebich for the suggestion to allow any amount of wrap and to be able to fill the remainder with color or transparency and still rotate the cylinder.

CAVEAT: No guarantee that this script will work on all platforms, nor that trapping of inconsistent parameters is complete and foolproof. Use At Your Own Risk.


EXAMPLES


No Pitch

Original Image

Arguments:
-m vertical

Arguments:
-m vertical -l 56

Arguments:
-m horizontal

Arguments:
-m horizontal -l 75

Arguments:
-m vertical -v background -b red

Arguments:
-m vertical -r 75

Rotation Animation
Arguments:
-m vertical -w 100 -a #
(where # varies from 0 to 360
in 30 degree increments)

Rotation Animation
Arguments:
-m vertical -w 50 -p 25 -a #
(where # varies from 0 to 360
in 30 degree increments)



With 20 Degree Pitch

Original Image

Arguments:
-m vertical -p 20

Arguments:
-m vertical -l 56 -p 20

Arguments:
-m horizontal -p 20

Arguments:
-m horizontal -l 75 -p 20

Arguments:
-m vertical -v background -b red -p 20

Arguments:
-m vertical -r 75 -p 20

Arguments:
-m vertical -p 20 -t

Arguments:
-m vertical -v background -b none -p 20 -t



With 45 Degree Pitch

Original Image

Arguments:
-m vertical -p 45

Arguments:
-m horizontal -p 20



Overlay Example 1

Input Image
(Source Image)

Background Image
(Source Image)

Background Image
(Source Image)

Arguments:
-m vertical -r 73 -l 120 -w 90 -p 5 -n 94 -e 2
-a 100 -v background -b none -f none -o +24+10

Arguments:
-m vertical -r 73 -l 120 -w 90 -p 5 -n 94 -e 2
-a -100 -v background -b none -f none -o -26+10

Arguments:
-m vertical -r 73 -l 120 -w 90 -p 5 -n 94 -e 2 -s 200
-a 100 -v background -b none -f none -o +24+10

Arguments:
-m vertical -r 73 -l 120 -w 90 -p 5 -n 94 -e 2 -s 200
-a -100 -v background -b none -f none -o -26+10



Overlay Example 2

Input Image
(Source Image)

Background Image
(Source Image)

Background Image
(Source Image)

Arguments:
-m vertical -r 79 -l 120 -w 90 -p 10 -n 96 -e 2
-a -100 -v background -b none -f none -o -22+15

Arguments:
-m vertical -r 73 -l 120 -w 90 -p 5 -n 94 -e 2
-a 100 -v background -b none -f none -o +20+15



Overlay Example 3

Input Image
(Source Image)

Background Image
(Source Image)

Background Image
(Source Image)

Arguments:
-m vertical -r 117 -l 150 -w 80 -p 17 -n 92 -e 2 \
-a -90 -v background -b none -f none -o -42+35

Arguments:
-m vertical -r 117 -l 150 -w 80 -p 17 -n 94 -e 2 \
-a 90 -v background -b none -f none -o +39+35



Overlay Example 4
(image width < radius)

Input Image
(width=50, height=64)

Input Image Padded From Width=50 To Width=74
(convert cartoon_cat.jpg -bordercolor none -border 12 cartoon_cat_pad.png)

Background Image
(Source Image)

Arguments:
-m vertical -r 73 -l 64 -w 19 -p 5 -n 94 -e 2
-a 0 -v background -b none -f none -o +24+10



What the script does is as follows:

  • Computes an arcsin distortion map for the radial dimension
  • Computes a linear distortion map for the length dimension
  • Uses composite displace to apply the two distortion maps to the image

This is equivalent to the following IM commands for the
case of the default vertically oriented cylinder.

  • width=`identify -ping -format %w $infile`
  • height=`identify -ping -format %h $infile`
  • xc=`convert xc: -format "%[fx:($width-1)/2]" info:`
  • factor=`convert xc: -format "%[fx:2/pi]" info:`
  • radius=`convert xc: -format "%[fx:$width/4]" info:`
  • length1=`convert xc: -format "%[fx:$height]" info:`
  • length1=`convert xc: -format "%[fx:$length1*cos(pi*$pitch/180)]" info:`
  • height1=`convert xc: -format "%[fx:$length1+$radius1]" info:`
  • ffx="ffx=$factor*asin(xd);"
  • convert -size ${width}x1 xc: -virtual-pixel black -fx \
    "xd=(i-$xc)/$radius; $ffx xs=0.5*(ffx+($xc-i)/($xc))+0.5; xd>1?1:xs" \
    -scale ${width}x${height1}! \ $tmp0
  • ffx="ffx=-sqrt(1-(xd)^2);"
  • convert -size ${width}x1 xc: -virtual-pixel black -fx \
    "xd=(i-$xc)/$radius; $ffx xs=0.5*(ffx)+0.5; abs(xd)>1?0.5:xs" \
    -scale ${width}x${height1}! \ $tmp1
  • length2=`convert xc: -format "%[fx:100*($length1)/$height]" info:`
  • convert $infile -resize 100x${length2}% \
    -gravity north -extent ${width}x${height1} $tmpA
  • composite $tmp0 $infile $tmp1 -virtual-pixel black \
    -displace ${xc}x${radius1} $tmpA