Fred's ImageMagick Scripts



    Licensing:

    Copyright © Fred Weinhaus

    My scripts are available free of charge for non-commercial (non-profit) 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 or not in the script, is restricted to the above licensing arrangements. It is also subject, in a subordinate manner, to the ImageMagick license, which can be found at: http://www.imagemagick.org/script/license.php

    Please read the Pointers For Use on my home page to properly install and customize my scripts.

PAGECURL


Applies a pagecurl effect to the lower right corner of an image.

Download Script

last modified: May 29, 2020



USAGE: pagecurl [-a amount] [-m mode] [-c color] [-b bgcolor] [-e ellipticity] [-x xcoord] [-y ycoord] [-g gcontrast] [-d dcontrast] infile [bgfile] outfile
USAGE: pagecurl [-help]

-a .... amount .......... amount of pagecurl expressed as percent of image
......................... width; integer>=0; default=50
-m .... mode ............ mode of shading curl; plain, grad or doublegrad;
......................... default=grad
-c .... color .......... color to apply to curl; any valid IM color;
......................... default=white
-b .... bgcolor ......... background color to apply to image where curled away;
......................... any valid IM color; default=none (transparent)
-e .... ellipticity ..... curl flattening from circle to ellipse;
......................... 0<=float<1; default=0 for circle; recommended value
......................... other 0 is 0.5 for ellipse shape
-x .... xcoord .......... x coordinate for apex of curl;
......................... default=right image edge
-y .... ycoord .......... y coordinate for apex of curl;
......................... default=upper image edge
-g .... gcontrast ....... contrast adjustment for mode=grad; 0<=integer<=100;
......................... increases contrast only; default=15
-d .... dcontrast ....... contrast adjustment for mode=doublegrad;
......................... -100<=integer<=100; positive increase contrast;
......................... negative decreases contrast; default=0

PURPOSE: Applies a pagecurl effect to the lower right corner of an image.

DESCRIPTION: PAGECURL Applies a pagecurl effect to the lower right corner of an image. The apex of the curl is nominally in the upper right corner of the image, but can be adjusted. The curl is always right to left. The curl can be shaded and/or colored. The removed area can be colored, transparent or filled with an optional same size background image if provided. Note that this is a 2D simulation and not a true 3D effect.

ARGUMENTS:

-a amount ... AMOUNT of pagecurl expressed as percent of image width. Values are integers>=0. The default=50. Caution: values below about 5 may fail.

-m mode ... MODE shading on the curl. Choices are: plain (or p), grad (or g) for gradient, or doublegrad (or d) for double gradient. Default=doublegrad.

-c color ... COLOR is the color to apply to curl. Any valid IM color is allowed. The default=white.

-b bgcolor ... BGCOLOR is the color to apply to curled away part of the image. Any valid IM color is allowed. The default=none for transparent. If a background file is provided, bgcolor must be none.

-e ellipticity ... ELLIPTICITY is the amount of curl flattening from a circle to an ellipse. Values are in range 0<=float<1. The default=0 for circle. Recommended value other 0 is 0.5 for ellipse shape.

-x xcoord ... XCOORD is the X coordinate for the apex of the curl. Values are 0<integers<width. The default is the right edge of the image.

-y ycoord ... YCOORD is the Y coordinate for the apex of the curl. Values are integers. The default is the upper edge of the image.

-g gcontrast ... GCONTRAST is the contrast adjustment for mode=grad. Values are in range 0<=integer<=100. This increases contrast only. The default=15

-d dcontrast ... DCONTRAST is the contrast adjustment for mode=doublegrad. Values are in range -100<=integer<=100. Positive values increase contrast. Negative values decrease contrast. The default=0

Thanks to Anthony Thyssen for critiqing the original version and for several useful suggestions for improvement.

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


Variation In Shading Mode With Ellipticity=0 (circle)

Original Image

Arguments:
-m plain

Arguments:
-m grad

Arguments:
-m doublegrad



Variation In Shading Mode With Color With Ellipticity=0 (circle)

Original Image

Arguments:
-m plain -c wheat

Arguments:
-m grad -c wheat

Arguments:
-m doublegrad -c wheat



Variation In Shading Mode With Ellipticity=0.5 (ellipse)

Original Image

Arguments:
-m plain -e 0.5

Arguments:
-m grad -e 0.5

Arguments:
-m doublegrad -e 0.5



Variation In Amount With Mode=grad AND Ellipticity=0 (circle)

Original Image

Arguments:
-a 20 -m grad

Arguments:
-a 50 -m grad

Arguments:
-a 80 -m grad



Variation In Amount With Mode=grad AND Ellipticity=0.5 (ellipse)

Original Image

Arguments:
-a 20 -m grad -e 0.5

Arguments:
-a 50 -m grad -e 0.5

Arguments:
-a 80 -m grad -e 0.5



Variation In Contrast For Mode=grad With Ellipticity=0 (cirlce)

Original Image

Arguments:
-m grad -g 10

Arguments:
-m grad -g 15

Arguments:
-m grad -g 20



Variation In Contrast For Mode=doublegrad With Ellipticity=0 (cirlce)

Original Image

Arguments:
-m grad -d -15

Arguments:
-m grad -d 0

Arguments:
-m grad -d 15



Variation In Apex Location For Mode=grad And Ellipticity=0 (circle)

Original Image

Arguments:
-m grad -y 100 -b green

Arguments:
-m grad -x 220 -b green

Arguments:
-m grad -x 255 -y -100 -b green



Animations
(scripts modified from one provided by Anthony Thyssen)

Original Image

image="mandril3.png"
for ((i=5; i<=105; i=i+10)); do
echo >&2 i=$i
pagecurl -a $i "$image" pam:
done | convert \
-dispose background \
-delay 100 "$image" \
-delay 10 - \
\( -delay 10 -clone -1-1 \) \
-delay 100 "$image" \
-loop 0 -layers Optimize \
pagecurl_animation1.gif

image="mandril3.png"
bgimage="zelda1.jpg"
for ((i=5; i<=105; i=i+10)); do
echo >&2 i=$i
pagecurl -a $i "$image" "$bgimage" pam:
done | convert \
-dispose background \
-delay 100 "$image" \
-delay 10 - \
\( -delay 10 -clone -1-1 \) \
-delay 100 "$image" \
-loop 0 -layers Optimize \
pagecurl_animation2.gif

image="mandril3.png"
bgimage="zelda1.jpg"
width=`identify -format '%[fx:w]' "$image"`
height=`identify -format '%[fx:h]' "$image"`
start=$((width+height/2))
start1=$((start-start/20))
for ((i=$start1; i>=0; i=i-$((start/20)))); do
x=$i; y=$((i-width))
echo >&2 i=$i x=$x y=$y
pagecurl -x $x -y $y "$image" "$bgimage" pam:
done | convert \
-dispose background \
-delay 100 "$image" \
-delay 10 - \
\( -clone -1-1 \) \
-delay 100 "$image" \
-loop 0 -layers Optimize \
pagecurl_animation3.gif



What the script does is as follows for mode=grad:

  • Defines the x,y location of the curl apex (default at upper right corner).
  • Compute approximate right side curl angle from amount
  • Compute ellipse radii a and b from amount
  • Compute angle to center of curl from amount and radius a
  • Create black rotated ellipse in white background trimmed to bounds of ellipse
  • Insert ellipse image into white image the size of input at the correct
    location so that center of ellipse is at center angle and bottom of ellipse
    is along bottom of image. This will be a mask image used later.
  • Compute length from apex to center of ellipse
  • Compute tangent points from apex to ellipse boundary from length and a and b radii
  • Draw white polygon in black background using apex and tangent points.
    This will be a mask used later
  • Create a gradient image using the -sparce-color barycentric method using the
    the two tangent points to define locations of white and black
  • Composite the input and gradient images with the triangle mask to overlay
    the gradient shaded triangle on the input image
  • Composite the ellipse mask with the previous image and the input image
    to replace to replace the shaded triangle where the ellipse is located
    with input image
  • Create mask for the area of the input image that was removed by the curl
    and composite that as an alpha channel with the previous result so that
    the removed area is transparent or background color

This is equivalent to the following IM commands:

  • ww=`convert $infile -ping -format "%w" info:`
  • hh=`convert $infile -ping -format "%h" info:`
  • wm1=`convert xc: -format "%[fx:$ww-1]" info:`
  • hm1=`convert xc: -format "%[fx:$hh-1]" info:`
  • xc=`convert xc: -format "%[fx:$ww/2]" info:`
  • yc=`convert xc: -format "%[fx:$hh/2]" info:`
  • x1=$xcoord
  • y1=$ycoord
  • dx=`convert xc: -format "%[fx:$ww*$amount/100]" info:`
  • rangle=`convert xc: -format "%[fx:(180/pi)*atan($dx/($hh-$y1))]" info:`
  • a=`convert xc: -format "%[fx:($dx+$ww-$x1)/pi]" info:`
  • b=`convert xc: -format "%[fx:$a*(1-$ellipticity)]" info:`
  • prx=`convert xc: -format "%[fx:$ww-$dx]" info:`
  • pry=$(($hh-1))
  • lenr=`convert xc: -format "%[fx:hypot(($y1-$pry),($x1-$prx))]" info:`
  • dangle=`convert xc: -format "%[fx:(180/pi)*asin(($a/2)/$lenr)]" info:`
  • angle=`convert xc: -format "%[fx:$rangle+$dangle]" info:`
  • convert -size ${ww}x${hh} xc:white -fill black \
    -draw "translate $xc,$yc rotate $angle ellipse 0,0 $a,$b 0,360" \
    -trim +repage $tmpA2
  • eww=`convert $tmpA2 -ping -format "%w" info:`
  • ehh=`convert $tmpA2 -ping -format "%h" info:`
  • y2=`convert xc: -format "%[fx:$hh-$ehh/2]" info:`
  • x2=`convert xc: -format "%[fx:$x1-($y2-$y1)*tan(pi*$angle/180)]" info:`
  • x0=`convert xc: -format "%[fx:$x2-$eww/2]" info:`
  • y0=`convert xc: -format "%[fx:$y2-$ehh/2]" info:`
  • convert -size ${ww}x${hh} xc:white -page ${eww}x${ehh}${offsets} $tmpA2 -flatten $tmpA2
  • len=`convert xc: -format "%[fx:hypot(($x2-$x1),($y2-$y1))]" info:`
  • angle2=`convert xc: -format "%[fx:-90+$angle]" info:`
  • p0x=0
  • p0y=-$len
  • A=`convert xc: -format "%[fx:$a*$a*$p0y*$p0y + $b*$b*$p0x*$p0x]" info:`
  • B=`convert xc: -format "%[fx:-2*$a*$a*$b*$b*$p0x]" info:`
  • C=`convert xc: -format "%[fx:$a*$a*$a*$a*($b*$b-$p0y*$p0y)]" info:`
  • p3x=`convert xc: -format "%[fx:(-$B-sqrt($B*$B-4*$A*$C))/(2*$A)]" info:`
  • p4x=`convert xc: -format "%[fx:(-$B+sqrt($B*$B-4*$A*$C))/(2*$A)]" info:`
  • p3y=`convert xc: -format "%[fx:($a*$a*$b*$b-$b*$b*$p0x*$p3x)/($a*$a*$p0y)]" info:`
  • p4y=`convert xc: -format "%[fx:($a*$a*$b*$b-$b*$b*$p0x*$p4x)/($a*$a*$p0y)]" info:`
  • x3=`convert xc: -format "%[fx:($p3x)cos(pi*$angle/180)-($p3y+$len)sin(pi*$angle/180)+$x1]" info:`
  • y3=`convert xc: -format "%[fx:($p3x)sin(pi*$angle/180)+($p3y+$len)cos(pi*$angle/180)+$y1]" info:`
  • x4=`convert xc: -format "%[fx:($p4x)cos(pi*$angle/180)-($p4y+$len)sin(pi*$angle/180)+$x1]" info:`
  • y4=`convert xc: -format "%[fx:($p4x)sin(pi*$angle/180)+($p4y+$len)cos(pi*$angle/180)+$y1]" info:`
  • convert -size ${ww}x${hh} xc:black \
    -fill white -stroke white -strokewidth $swidth \
    -draw "polygon $x1,$y1 $x3,$y3 $x4,$y4" $tmpA3
  • lo=$gcontrast
  • hi=$((100-$lo))
  • process="-level ${lo}x${hi}% +level-colors black,$color"
  • convert $infile \
    \( -size ${ww}x${hh} xc: -sparse-color Barycentric \
    "$x3,$y3 white $x4,$y4 black" $process \) \
    $tmpA3 -compose over -composite $tmpA4
  • convert $infile $tmpA4 $tmpA2 -alpha off -compose over -composite $tmpA4
  • if [ "$bgcolor" = "none" -a "$bgfile" != "" ]; then
    back="$bgfile +swap"
    else
    back="-background $bgcolor"
    fi
  • convert $tmpA4 \( -size ${ww}x${hh} xc:white \
    -fill red -draw "line $x1,$y1 $x4,$y4" \
    -fill red -draw "translate $x2,$y2 rotate $angle ellipse 0,0 $a,$b 0,360" \
    -fill black -draw "color $wm1,$hm1 floodfill" \
    -fill white +opaque black -blur 2x65000 -level 50x100% \) \
    -alpha off -compose copy_opacity -composite \
    -compose over $back -flatten $outfile