Advertisement
Guest User

3Dcover

a guest
May 14th, 2013
215
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 30.04 KB | None | 0 0
  1. #!/bin/bash
  2. #
  3. # Developed by Fred Weinhaus 1/3/2013 .......... revised 5/11/2013
  4. #
  5. # USAGE: 3Dcover [-s side] [-a angle] [-e exfact] [-w weight] [-t tone]
  6. # [-o opacity] [-d diameter] [-r ramp] [-g gamma] [-v vcolor] [-m method]
  7. # [-u umbra] [-p penumbra] [-l length] [-b bcolor] [-x xyoffset] [-f fuzzval]
  8. # infile outfile
  9. #
  10. # USAGE: 3Dcover [-h or -help]
  11. #
  12. # OPTIONS:
  13. #
  14. # -s side length of left or right side of cover; pixels or
  15. # percent of original image; if pixels, the integer>0;
  16. # if percent then 0<float<100 and % must be included;
  17. # default="20%"
  18. # -a angle rotation angle in deg; -90<integer<90; default=25;
  19. # not recommended beyond 60 or -60 when method=ground
  20. # -e exfact perspective exaggeration factor; 0<float<3;
  21. # value of 1 is normal perspective; value of 0.5
  22. # is close to orthographic; default=1
  23. # -w weight line (stroke) weight for translucent gray join line
  24. # between front and side; integer>0; default=2
  25. # -t tone tone (brightness in percent) of join line;
  26. # 0<=integer<=100; 100 is white; 0 is black; default=100
  27. # -o opacity opacity (percent) of join line; 0<=integer<=100;
  28. # 0 is transparent and 100 is fully opaque; default=0
  29. # -d diameter diameter of vignette in percent of size of front;
  30. # integer>=0; default=0 (no vignette); nominal is 100
  31. # -r ramp ramp (taper) of vignette effect; integer>=0;
  32. # default=75
  33. # -g gamma gamma adjustment of vignette; float>0; values less
  34. # than 1 will lighten/soften the vignette and values
  35. # less than 1 will darker/harden the vignette;
  36. # default=0.5
  37. # -v vcolor vignette color; any valid opaque IM color;
  38. # default=black
  39. # -m method shadow method (type); choices are: none (n),
  40. # backdrop (b) and ground (g); default=none
  41. # -u umbra graylevel percent value for dark inner part of shadow;
  42. # 0<=integer<=100; default=50
  43. # -p penumbra extent in pixels of light outer part of shadow;
  44. # integer>0; default=10 for method=backdrop and
  45. # default=6 for method=ground
  46. # -l length length of shadow; for method=backdrop, it is the
  47. # offset between the cover and the shadow with
  48. # default=15; for method=ground, it is a factor of
  49. # the length of the side in perspective and the
  50. # default=1.5
  51. # -b bcolor background color; any valid IM color including
  52. # transparent (none); default=white
  53. # -x xyoffset offset of shadow for method=ground to refine
  54. # alignment, if needed; comma separate pair of
  55. # integers; default="0,0"
  56. # -f fuzzval fuzz factor for trimming the front and side
  57. # perspectives before joining together and trimming the
  58. # final image; integer>=0; default=0
  59. #
  60. ###
  61. #
  62. # NAME: 3DCOVER
  63. #
  64. # PURPOSE: To wrap an image around the front and left or right side of box
  65. # viewed in rotated perspective.
  66. #
  67. # DESCRIPTION: 3DCOVER wraps an image around the front and left or right side
  68. # of box viewed in rotated perspective. The box size will be proportional to
  69. # the dimensions of the two sides. Optionally, the box cover may have a
  70. # vignette effect shown on the front face and a translucent gray line may be
  71. # drawn on the join between the two faces. Two kinds of shadows may be cast;
  72. # either a backdrop or ground shadow. The box may be rotated either direction
  73. # and its perspective exaggeration controlled.
  74. #
  75. #
  76. # ARGUMENTS:
  77. #
  78. # -s side ... SIDE is the length of left or right side of the cover. Values
  79. # are either pixels or percent of the width of the original image. If in
  80. # pixels, then values are integers>0. If percent, then values are 0<floats<100
  81. # with a trailing % and no spaces. The default="20%"
  82. #
  83. # -a angle ... ANGLE is the box rotation angle in degrees. Values are
  84. # -90<integers<90. The default=25. Note that it is not recommended to go
  85. # beyond 60 or -60, when method=ground. The (pseudo-)shadow will not look right
  86. # and may be misplaced. Note, if angle is within 2 degrees of zero, it will
  87. # be converted to 0.
  88. #
  89. # -e exfact ... EXFACT is the perspective exaggeration factor. Values are
  90. # 0<floats<3. A value of 1 is normal perspective and a value of 0.5 is close
  91. # to orthographic. The default=1.
  92. #
  93. # -w weight ... WEIHGT is the line (stroke) weight for a translucent gray join
  94. # line between the front and side faces. Values are integers>0. The default=2.
  95. #
  96. # -t tone ... TONE is the brightness in percent of the join line. Values are
  97. # 0<=integers<=100. A value of 100 is white and a value of 0 is black. The
  98. # default=100 (white).
  99. #
  100. # -o opacity ... OPACITY of the join line in percent. Values are
  101. # 0<=integers<=100. A value of 0 is transparent and a value of 100 is fully
  102. # opaque. The default=0 indicates no join line.
  103. #
  104. # -d diameter ... DIAMETER of the vignette effect in percent of the size of
  105. # the front face. The vignette is only applied to the front face. Values are
  106. # integers>=0. The default=0 indicates no vignette. The nominal value is 100.
  107. #
  108. # -r ramp ... RAMP is the taper or roll-off of the vignette effect. Values are
  109. # integers>=0. The default=75.
  110. #
  111. # -g gamma... GAMMA is the gamma adjustment of vignette. Values are floats>0.
  112. # Values less than 1 will lighten/soften the vignette and values less than 1
  113. # will darker/harden the vignette. The default=0.5.
  114. #
  115. # -v vcolor ... VCOLOR is the vignette color. Any valid opaque IM color is
  116. # allowed. The default=black.
  117. #
  118. # -m method ... METHOD is theshadow method (type). The choices are: none (n),
  119. # backdrop (b) and ground (g). The default=none.
  120. #
  121. # -u umbra ... UMBRA is the graylevel percent value for the dark inner part
  122. # of the shadow. Values are 0<=integers<=100. The default=50.
  123. #
  124. # -p penumbra ... PENUMBRA is the extent in pixels of the light outer part of
  125. # of the shadow. Values are integers>0. The default=10 for method=backdrop and
  126. # the default=6 for method=ground.
  127. #
  128. # -l length ... LENGTH of the shadow. For method=backdrop, it is the offset
  129. # between the box and the shadow with values as integers>0 and a default=15.
  130. # For method=ground, it is a factor of the length of the side in perspective
  131. # with values as floats>0 and the default=1.5.
  132. #
  133. # -b bcolor ... BCOLOR is the background color. Any valid IM color including
  134. # transparent or none is allowed. The default=white.
  135. #
  136. # -x xyoffset ... XYOFFSET is an offset correction for the shadow for \
  137. # method=ground to refine its alignment, if needed. Values are a comma
  138. # separate pair of integers. The default="0,0".
  139. #
  140. # -f fuzzval ... FUZZVAL is the fuzz factor for trimming the front and side
  141. # perspectives images before joining them together and trimming the final
  142. # image. Values are integers>=0. The default=0.
  143. #
  144. # REQUIREMENTS: This script requires my 3Drotate script to function.
  145. #
  146. # NOTE: For mode=ground, the ground shadow works between IM 6.6.0.10 and
  147. # 6.7.2.0; is unknow between 6.7.2.1 and 6.7.2.9; fails for between 6.7.2.10
  148. # and 6.7.6.9; works again from 6.7.6.10 to 6.8.3.4; fails again from 6.8.3.5
  149. # to 6.8.3.9; then works again starting after 6.8.3.9. The shadow will be
  150. # slightly different and there will be extra white space on the shadow side,
  151. # which can be removed using the -f fuzzval argument for versions after 6.8.3.9.
  152. #
  153. # CAVEAT: No guarantee that this script will work on all platforms,
  154. # nor that trapping of inconsistent parameters is complete and
  155. # foolproof. Use At Your Own Risk.
  156. #
  157. ######
  158. #
  159.  
  160. # 5.14.2013
  161. imdir="/cygdrive/c/Program Files/ImageMagick-6.8.5-Q16/convert"
  162. PATH="${imdir}:${PATH}"
  163.  
  164. scriptpath="/cygdrive/c/cygwin/home/testbox"
  165. PATH="${PATH}:${scriptpath}"
  166. # end mod
  167.  
  168. # set default values
  169. side=20% # length of side: pixels or percent of original image
  170. angle=25 # pan rotation angle; -90<float<90
  171. exfact=1 # perspective exaggeration factor; float>0
  172. weight=2 # line (stroke) weight for translucent gray join line
  173. tone=100 # tone (brightness in percent) of translucent gray line; 100 is white; 0 is black; integer
  174. opacity=0 # opacity in percent of gray line drawn along join between left and right sides; integer; default=0 (no line); nominal 20
  175. diameter=0 # diameter of vignette in percent of size of front face; default=0 (no vignette); nominal=100
  176. ramp=75 # vignette ramp; integer>=0
  177. gamma=0.5 # gamma adjustment of vignette ramp rolloff; float>0
  178. vcolor=black # vignette color; default=black
  179. method="none" # shadow method; backdrop (b) or ground (g) or none (n); default=none
  180. umbra=50 # shadow umbra percent intensity for both methods (nominal 50)
  181. penumbra="" # shadow penumbra size; sigma blur amount for both methods; method backdrop (nominal 10); method ground (nominal 6)
  182. length="" # shadow length; offset for method backdrop in pixels (nominal 15); length factor for method ground (nominal 1.5)
  183. bcolor=white # background color; default=transparent
  184. xyoffset=0,0 # offset of shadow for method=ground to refine alignment
  185. fuzzval=0 # trim fuzz; may be needed esp for large angles if shadow goes haywire
  186.  
  187. # set directory for temporary files
  188. dir="." # suggestions are dir="." or dir="/tmp"
  189.  
  190. # set up functions to report Usage and Usage with Description
  191. PROGNAME=`type $0 | awk '{print $3}'` # search for executable on path
  192. PROGDIR=`dirname $PROGNAME` # extract directory of program
  193. PROGNAME=`basename $PROGNAME` # base name of program
  194. usage1()
  195. {
  196. echo >&2 ""
  197. echo >&2 "$PROGNAME:" "$@"
  198. sed >&2 -n '/^###/q; /^#/!q; s/^#//; s/^ //; 4,$p' "$PROGDIR/$PROGNAME"
  199. }
  200. usage2()
  201. {
  202. echo >&2 ""
  203. echo >&2 "$PROGNAME:" "$@"
  204. sed >&2 -n '/^######/q; /^#/!q; s/^#*//; s/^ //; 4,$p' "$PROGDIR/$PROGNAME"
  205. }
  206.  
  207.  
  208. # function to report error messages
  209. errMsg()
  210. {
  211. echo ""
  212. echo $1
  213. echo ""
  214. usage1
  215. exit 1
  216. }
  217.  
  218.  
  219. # function to test for minus at start of value of second part of option 1 or 2
  220. checkMinus()
  221. {
  222. test=`echo "$1" | grep -c '^-.*$'` # returns 1 if match; 0 otherwise
  223. [ $test -eq 1 ] && errMsg "$errorMsg"
  224. }
  225.  
  226. # test for correct number of arguments and get values
  227. if [ $# -eq 0 ]
  228. then
  229. # help information
  230. echo ""
  231. usage2
  232. exit 0
  233. elif [ $# -gt 36 ]
  234. then
  235. errMsg "--- TOO MANY ARGUMENTS WERE PROVIDED ---"
  236. else
  237. while [ $# -gt 0 ]
  238. do
  239. # get parameter values
  240. case "$1" in
  241. -h|-help) # help information
  242. echo ""
  243. usage2
  244. exit 0
  245. ;;
  246. -s) # get side
  247. shift # to get the next parameter
  248. #test if parameter starts with minus sign
  249. errorMsg="--- INVALID SIDE SPECIFICATION ---"
  250. checkMinus "$1"
  251. side=`expr "$1" : '\([.0-9%]*\)'`
  252. [ "$side" = "" ] && errMsg "--- SIDE=$side MUST BE A NON-NEGATIVE FLOAT WITH TRAILING OPTIONAL % CHARACTER ---"
  253. ;;
  254. -a) # get angle
  255. shift # to get the next parameter
  256. # test if parameter starts with minus sign
  257. #errorMsg="--- INVALID ANGLE SPECIFICATION ---"
  258. #checkMinus "$1"
  259. angle=`expr "$1" : '\([-0-9]*\)'`
  260. [ "$angle" = "" ] && errMsg "--- ANGLE=$angle MUST BE A NON-NEGATIVE INTEGER ---"
  261. testA=`echo "$angle >= 90" | bc`
  262. testB=`echo "$angle <= -90" | bc`
  263. [ $testA -eq 1 -o $testB -eq 1 ] && errMsg "--- ANGLE=$angle MUST BE AN INTEGER BETWEEN -90 AND 90 (EXCLUSIVE) ---"
  264. ;;
  265. -e) # get exfact
  266. shift # to get the next parameter
  267. # test if parameter starts with minus sign
  268. errorMsg="--- INVALID EXFACT SPECIFICATION ---"
  269. checkMinus "$1"
  270. exfact=`expr "$1" : '\([.0-9]*\)'`
  271. [ "$exfact" = "" ] && errMsg "--- EXFACT=$exfact MUST BE A NUMBER ---"
  272. testA=`echo "$exfact <= 0" | bc`
  273. testB=`echo "$exfact >= 3" | bc`
  274. [ $testA -eq 1 -o $testB -eq 1 ] && errMsg "--- EXFACT=$exfact MUST BE A FLOAT LARGER THAN 0 AND SMALLER THAN 3 ---"
  275. ;;
  276. -w) # get weight
  277. shift # to get the next parameter
  278. # test if parameter starts with minus sign
  279. errorMsg="--- INVALID WEIGHT SPECIFICATION ---"
  280. checkMinus "$1"
  281. weight=`expr "$1" : '\([0-9]*\)'`
  282. [ "$weight" = "" ] && errMsg "--- WEIGHT=$weight MUST BE A NON-NEGATIVE INTEGER ---"
  283. testA=`echo "$weight == 0" | bc`
  284. [ $testA -eq 1 ] && errMsg "--- WEIGHT=$weight MUST BE A POSITIVE INTEGER ---"
  285. ;;
  286. -t) # get tone
  287. shift # to get the next parameter
  288. # test if parameter starts with minus sign
  289. errorMsg="--- INVALID TONE SPECIFICATION ---"
  290. checkMinus "$1"
  291. tone=`expr "$1" : '\([0-9]*\)'`
  292. [ "$tone" = "" ] && errMsg "--- TONE=$tone MUST BE A NON-NEGATIVE INTEGER ---"
  293. testA=`echo "$tone >= 100" | bc`
  294. [ $testA -eq 1 ] && errMsg "--- TONE=$tone MUST BE AN INTEGER BETWEEN 0 AND 100 ---"
  295. ;;
  296. -o) # get opacity
  297. shift # to get the next parameter
  298. # test if parameter starts with minus sign
  299. errorMsg="--- INVALID OPACITY SPECIFICATION ---"
  300. checkMinus "$1"
  301. opacity=`expr "$1" : '\([0-9]*\)'`
  302. [ "$opacity" = "" ] && errMsg "--- OPACITY=$opacity MUST BE A NON-NEGATIVE INTEGER ---"
  303. testA=`echo "$opacity > 100" | bc`
  304. [ $testA -eq 1 ] && errMsg "--- OPACITY=$opacity MUST BE AN INTEGER BETWEEN 0 AND 100 ---"
  305. ;;
  306. -d) # get diameter
  307. shift # to get the next parameter
  308. # test if parameter starts with minus sign
  309. errorMsg="--- INVALID DIAMETER SPECIFICATION ---"
  310. checkMinus "$1"
  311. diameter=`expr "$1" : '\([0-9]*\)'`
  312. [ "$diameter" = "" ] && errMsg "--- DIAMETER=$diameter MUST BE A NON-NEGATIVE INTEGER ---"
  313. ;;
  314. -r) # get ramp
  315. shift # to get the next parameter
  316. # test if parameter starts with minus sign
  317. errorMsg="--- INVALID RAMP SPECIFICATION ---"
  318. checkMinus "$1"
  319. ramp=`expr "$1" : '\([0-9]*\)'`
  320. [ "$ramp" = "" ] && errMsg "--- RAMP=$ramp MUST BE A NON-NEGATIVE INTEGER ---"
  321. ;;
  322. -g) # get gamma
  323. shift # to get the next parameter
  324. # test if parameter starts with minus sign
  325. errorMsg="--- INVALID GAMMA SPECIFICATION ---"
  326. checkMinus "$1"
  327. gamma=`expr "$1" : '\([.0-9]*\)'`
  328. [ "$gamma" = "" ] && errMsg "--- GAMMA=$gamma MUST BE A NON-NEGATIVE FLOAT ---"
  329. testA=`echo "$gamma == 0" | bc`
  330. [ $testA -eq 1 ] && errMsg "--- GAMMA=$gamma MUST BE A POSITIVE FLOAT ---"
  331. ;;
  332. -v) # get vcolor
  333. shift # to get the next parameter
  334. # test if parameter starts with minus sign
  335. errorMsg="--- INVALID VCOLOR SPECIFICATION ---"
  336. checkMinus "$1"
  337. vcolor="$1"
  338. ;;
  339. -m) # get method
  340. shift # to get the next parameter
  341. # test if parameter starts with minus sign
  342. errorMsg="--- INVALID METHOD SPECIFICATION ---"
  343. checkMinus "$1"
  344. method="$1"
  345. method=`echo "$method" | tr "[:upper:]" "[:lower:]"`
  346. case "$method" in
  347. none|n) method="none" ;;
  348. backdrop|b) method="backdrop" ;;
  349. ground|g) method="ground" ;;
  350. *) errMsg "--- METHOD=$method IS AN INVALID VALUE ---"
  351. esac
  352. ;;
  353. -u) # get umbra
  354. shift # to get the next parameter
  355. # test if parameter starts with minus sign
  356. errorMsg="--- INVALID UMBRA SPECIFICATION ---"
  357. checkMinus "$1"
  358. umbra=`expr "$1" : '\([0-9]*\)'`
  359. [ "$umbra" = "" ] && errMsg "--- UMBRA=$umbra MUST BE A NON-NEGATIVE INTEGER ---"
  360. testA=`echo "$umbra > 100" | bc`
  361. [ $testA -eq 1 ] && errMsg "--- UMBRA=$umbra MUST BE AN INTEGER BETWEEN 0 AND 100 ---"
  362. ;;
  363. -p) # get penumbra
  364. shift # to get the next parameter
  365. # test if parameter starts with minus sign
  366. errorMsg="--- INVALID PENUMBRA SPECIFICATION ---"
  367. checkMinus "$1"
  368. penumbra=`expr "$1" : '\([0-9]*\)'`
  369. [ "$penumbra" = "" ] && errMsg "--- PENUMBRA=$penumbra MUST BE A NON-NEGATIVE INTEGER ---"
  370. testA=`echo "$penumbra == 0" | bc`
  371. [ $testA -eq 1 ] && errMsg "--- PENUMBRA=$penumbra MUST BE AN INTEGER LARGER THAN 0 ---"
  372. ;;
  373. -l) # get length
  374. shift # to get the next parameter
  375. # test if parameter starts with minus sign
  376. errorMsg="--- INVALID LENGTH SPECIFICATION ---"
  377. checkMinus "$1"
  378. length=`expr "$1" : '\([.0-9]*\)'`
  379. [ "$length" = "" ] && errMsg "--- LENGTH=$length MUST BE A NUMBER ---"
  380. testA=`echo "$length == 0" | bc`
  381. [ $testA -eq 1 ] && errMsg "--- LENGTH=$length MUST BE A NUMBER LARGER THAN 0 ---"
  382. ;;
  383. -b) # get bcolor
  384. shift # to get the next parameter
  385. # test if parameter starts with minus sign
  386. errorMsg="--- INVALID BCOLOR SPECIFICATION ---"
  387. checkMinus "$1"
  388. bcolor="$1"
  389. ;;
  390. -x) # get xyoffset
  391. shift # to get the next parameter
  392. # test if parameter starts with minus sign
  393. #errorMsg="--- INVALID XYOFFSET SPECIFICATION ---"
  394. #checkMinus "$1"
  395. test=`echo "$1" | tr "," " " | wc -w`
  396. [ $test -le 1 -o $test -gt 2 ] && errMsg "--- INCORRECT NUMBER OF XYOFFSETS SUPPLIED ---"
  397. xyoffset=`expr "$1" : '\([-0-9]*,[-0-9]*\)'`
  398. [ "$xyoffset" = "" ] && errMsg "--- XYOFFSET=$xyoffset MUST BE A PAIR OF INTEGERS SEPARATED BY A COMMA ---"
  399. xyoffset=`echo "$xyoffset" | sed 's/ *//g'`
  400. [ "$xyoffset" = "" -o "$xyoffset" = "," ] && errMsg "--- NO XYOFFSETS SUPPLIED ---"
  401. ;;
  402. -f) # get fuzzval
  403. shift # to get the next parameter
  404. # test if parameter starts with minus sign
  405. errorMsg="--- INVALID FUZZVAL SPECIFICATION ---"
  406. checkMinus "$1"
  407. fuzzval=`expr "$1" : '\([0-9]*\)'`
  408. [ "$fuzzval" = "" ] && errMsg "--- FUZZVAL=$fuzzval MUST BE A NON-NEGATIVE INTEGER ---"
  409. ;;
  410. -) # STDIN and end of arguments
  411. break
  412. ;;
  413. -*) # any other - argument
  414. errMsg "--- UNKNOWN OPTION ---"
  415. ;;
  416. *) # end of arguments
  417. break
  418. ;;
  419. esac
  420. shift # next option
  421. done
  422. #
  423. # get infile and outfile
  424. infile=$1
  425. outfile=$2
  426. fi
  427.  
  428. # test that infile provided
  429. [ "$infile" = "" ] && errMsg "NO INPUT FILE SPECIFIED"
  430.  
  431. # test that outfile provided
  432. [ "$outfile" = "" ] && errMsg "NO OUTPUT FILE SPECIFIED"
  433.  
  434.  
  435. # setup temporary images
  436. tmpA1="$dir/3Dcover_1_$$.mpc"
  437. tmpB1="$dir/3Dcover_1_$$.cache"
  438. tmpL1="$dir/3Dcover_L_$$.mpc"
  439. tmpL2="$dir/3Dcover_L_$$.cache"
  440. tmpR1="$dir/3Dcover_R_$$.mpc"
  441. tmpR2="$dir/3Dcover_R_$$.cache"
  442. tmpS1="$dir/3Dcover_S_$$.mpc"
  443. tmpS2="$dir/3Dcover_S_$$.cache"
  444. trap "rm -f $tmpA1 $tmpB1 $tmpL1 $tmpL2 $tmpR1 $tmpR2 $tmpS1 $tmpS2; exit 0" 0
  445. trap "rm -f $tmpA1 $tmpB1 $tmpL1 $tmpL2 $tmpR1 $tmpR2 $tmpS1 $tmpS2; exit 1" 1 2 3 15
  446.  
  447. # get im_version
  448. im_version=`convert -list configure | \
  449. sed '/^LIB_VERSION_NUMBER /!d; s//,/; s/,/,0/g; s/,0*\([0-9][0-9]\)/\1/g' | head -n 1`
  450.  
  451. # colorspace RGB and sRGB swapped between 6.7.5.5 and 6.7.6.7
  452. # though probably not resolved until the latter
  453. # then -colorspace gray changed to linear between 6.7.6.7 and 6.7.8.2
  454. # then -separate converted to linear gray channels between 6.7.6.7 and 6.7.8.2,
  455. # though probably not resolved until the latter
  456. # so -colorspace HSL/HSB -separate and -colorspace gray became linear
  457. # but we need to use -set colorspace RGB before using them at appropriate times
  458. # so that results stay as in original script
  459. # The following was determined from various version tests using 3Dcover
  460. # For mode=ground, it works between IM 6.6.0.10 and 6.7.2.0
  461. # unknow between 6.7.2.1 and 6.7.2.9
  462. # but fails for between 6.7.2.10 and 6.7.6.9
  463. # then works again from 6.7.6.10 to 6.8.3.4
  464. # then fails again from 6.8.3.5 to 6.8.3.9
  465. # then starting with 6.8.4.0 the shadow will be slightly different and there will be extra white space on the shadow side
  466. # For mode=backdrop and mode=none (latter with or without vignette),
  467. # it works normally for IM 6.7.4.10, 6.7.6.10 and 6.8.1.5, 6.8.5.6
  468. if [ "$im_version" -lt "06070607" -o "$im_version" -gt "06070707" ]; then
  469. setcspace="-set colorspace RGB"
  470. else
  471. setcspace=""
  472. fi
  473.  
  474. # read the input image into the temporary cached image and test if valid
  475. convert -quiet -regard-warnings "$infile" +repage "$tmpA1" ||
  476. errMsg "--- FILE $infile DOES NOT EXIST OR IS NOT AN ORDINARY FILE, NOT READABLE OR HAS ZERO size ---"
  477.  
  478. # get image dimensions
  479. ww=`convert $tmpA1 -format "%w" info:`
  480. hh=`convert $tmpA1 -format "%h" info:`
  481. hm1=$((hh-1))
  482.  
  483. # convert side from percent to pixels if needed
  484. test=`echo "$side" | grep "%"`
  485. if [ "$test" != "" ]; then
  486. side=`echo "$side" | sed 's/%//g'`
  487. side=`convert xc: -format "%[fx:round($side*$ww/100)]" info:`
  488. fi
  489. #echo "side=$side"
  490.  
  491. # setup default penumbra
  492. if [ "$penumbra" = "" -a "$method" = "backdrop" ]; then
  493. penumbra=10
  494. elif [ "$penumbra" = "" -a "$method" = "ground" ]; then
  495. penumbra=6
  496. fi
  497.  
  498. # setup default length
  499. if [ "$length" = "" -a "$method" = "backdrop" ]; then
  500. length=15
  501. elif [ "$length" = "" -a "$method" = "ground" ]; then
  502. length=1.5
  503. fi
  504.  
  505. # compute crop of input into front and side
  506. sign=`convert xc: -format "%[fx:$angle<0?0:1]" info:`
  507. if [ $sign -eq 1 ]; then
  508. #crop side on left and rotate about join line
  509. rangle=$angle
  510. langle=$((angle-90))
  511. wl=$side
  512. wr=$((ww-wl+1))
  513. lcrop="${wl}x${hh}+0+0"
  514. rcrop="${wr}x${hh}+${wl}+0"
  515. shadsign="-"
  516. else
  517. #crop side on right and rotate about join line
  518. langle=$angle
  519. rangle=$((90+angle))
  520. wr=$side
  521. wl=$((ww-wr+1))
  522. lcrop="${wl}x${hh}+0+0"
  523. rcrop="${wr}x${hh}+${wl}+0"
  524. shadsign="+"
  525. fi
  526.  
  527. # crop the input into left and right faces
  528. convert $tmpA1 -crop $lcrop +repage $tmpL1
  529. convert $tmpA1 -crop $rcrop +repage $tmpR1
  530.  
  531. # apply vignette to appropriate face
  532. if [ "$diameter" != "0" ]; then
  533. if [ $sign -eq 1 ]; then
  534. cx=`convert $tmpR1 -format "%[fx:w/2]" info:`
  535. cy=`convert $tmpR1 -format "%[fx:h/2]" info:`
  536. ww2=`convert xc: -format "%[fx:$cx*$diameter/100]" info:`
  537. hh2=`convert xc: -format "%[fx:$cy*$diameter/100]" info:`
  538. args="0,0 $ww2,$hh2 0,360"
  539. convert $tmpR1 \
  540. \( -clone 0 -fill $vcolor -colorize 100% \) \
  541. \( -clone 0 -fill white -colorize 100% -fill black \
  542. -draw "translate $cx,$cy ellipse $args" -blur 0x$ramp -gamma $gamma \) \
  543. $setcspace -compose over -composite $tmpR1
  544. else
  545. cx=`convert $tmpL1 -format "%[fx:w/2]" info:`
  546. cy=`convert $tmpL1 -format "%[fx:h/2]" info:`
  547. ww2=`convert xc: -format "%[fx:$cx*$diameter/100]" info:`
  548. hh2=`convert xc: -format "%[fx:$cy*$diameter/100]" info:`
  549. args="0,0 $ww2,$hh2 0,360"
  550. convert $tmpL1 \
  551. \( -clone 0 -fill $vcolor -colorize 100% \) \
  552. \( -clone 0 -fill white -colorize 100% -fill black \
  553. -draw "translate $cx,$cy ellipse $args" -blur 0x$ramp -gamma $gamma \) \
  554. $setcspace -compose multiply -composite $tmpL1
  555. fi
  556. #echo "cx=$cx; cy=$cy; ww2=$ww2; hh2=$hh2; ww=$ww, hh=$hh"
  557. fi
  558.  
  559. # do perspective rotate on left face
  560. xoff=`convert $tmpL1 -format "%[fx:w/2]" info:`
  561. 3Drotate pan=$langle pef=$exfact auto=out idx=$xoff idy=0 bgcolor=none skycolor=none $tmpL1 $tmpL1
  562.  
  563. # do perspective rotate on right face
  564. xoff=`convert $tmpR1 -format "%[fx:-w/2]" info:`
  565. 3Drotate pan=$rangle pef=$exfact auto=out idx=$xoff idy=0 bgcolor=none skycolor=none $tmpR1 $tmpR1
  566.  
  567. # trim images and get length left image for offset for right image and length of right image
  568. convert $tmpL1 -fuzz $fuzzval% -trim +repage $tmpL1
  569. convert $tmpR1 -fuzz $fuzzval% -trim +repage $tmpR1
  570. wl=`convert $tmpL1 -format "%w" info:`
  571. wr=`convert $tmpR1 -format "%w" info:`
  572. wlm1=$((wl-1))
  573. wrm1=$((wr-1))
  574. #echo "wl=$wl; wr=$wr;"
  575.  
  576. # append the two parts and draw translucent line
  577. # shift right image two pixels to the left to avoid antialiased seem between the two parts
  578. xs=$((wl-2))
  579. opacity=`convert xc: -format "%[fx:$opacity/100]" info:`
  580. convert -page +0+0 $tmpL1 -page +${xs}+0 $tmpR1 -background none -layers merge +repage \
  581. -alpha on -channel rgba -fill "graya($tone%,$opacity)" \
  582. -stroke "graya($tone%,$opacity)" -strokewidth $weight -draw "line $wl,1 $wl,$((hh-1))" \
  583. +repage $tmpA1
  584.  
  585.  
  586. # set background color
  587. if [ "$bcolor" != "" ]; then
  588. coloring="-background $bcolor -flatten"
  589. else
  590. coloring=""
  591. fi
  592.  
  593.  
  594. # add shadow
  595. if [ "$method" = "none" ]; then
  596. convert $tmpA1 $coloring $outfile
  597.  
  598. elif [ "$method" = "backdrop" ]; then
  599.  
  600. [ "$penumbra" = "" ] && penumbra=10
  601. [ "$length" = "" ] && length=15
  602. # invert umbra from brightness to opacity for -shadow
  603. umbra=$((100-umbra))
  604.  
  605. convert $tmpA1 \
  606. \( +clone -background black -shadow ${umbra}x${penumbra}${shadsign}${length}+${length} \) \
  607. +swap -background none -layers merge +repage \
  608. $coloring $outfile
  609.  
  610. elif [ "$method" = "ground" ]; then
  611.  
  612. angletest1=`convert xc: -format "%[fx:(abs($angle))<2?1:0]" info:`
  613. angletest2=`convert xc: -format "%[fx:(90-abs($angle))<2?1:0]" info:`
  614. # echo "angletest1=$angletest1; angletest2=$angletest2"
  615. [ $angletest2 -eq 1 -o $angletest2 -eq 1 ] && errMsg "--- ANGLE TOO CLOSE TO 0 OR 90 OR -90 WITH METHOD=GROUND ---"
  616.  
  617. # compute shadow triangle and merge with image
  618. [ "$penumbra" = "" ] && penumbra=6
  619. [ "$length" = "" ] && length=1.5
  620.  
  621. # compute height of bottom outside triangle of each face
  622. # make non-transparent black and transparent white
  623. # floodfill black at upper white triangle
  624. # draw black line on larger side of face to cover aliased pixels from perspective along the seam
  625. # trim to black/white diagonal rectangle
  626. # get height
  627. # compute diagonal angles from length and height
  628.  
  629. hl=`convert $tmpL1 -fill black +opaque none -fill white -opaque none \
  630. -fill black -draw "color 0,0 floodfill" -alpha off \
  631. -fill black -draw "line $wlm1,0 $wlm1,$hm1" -alpha off \
  632. -trim +repage -format "%h" info:`
  633.  
  634. aleft=`convert xc: -format "%[fx:atan2($hl,$wl)]" info:`
  635.  
  636. hr=`convert $tmpR1 -fill black +opaque none -fill white -opaque none \
  637. -fill black -draw "color $wrm1,0 floodfill" -alpha off \
  638. -fill black -draw "line 0,0 0,$hm1" -alpha off \
  639. -trim +repage -format "%h" info:`
  640.  
  641. aright=`convert xc: -format "%[fx:atan2($hr,$wr)]" info:`
  642. # echo "hl=$hl; hr=$hr; aleft=$aleft; aright=$aright;"
  643.  
  644. # compute vertically inverted coordinates (0,0 at bottom left side of rectangle), then flip image
  645. ff=$length
  646. penumbra2=$((2*penumbra))
  647.  
  648. if [ $sign -eq 0 ]; then
  649.  
  650. # shadow on right side
  651. bx=0
  652. by=0
  653. mx=`convert xc: -format "%[fx:round($ff*$wr)]" info:`
  654. my=`convert xc: -format "%[fx:round($ff*$hr)]" info:`
  655. # add fudgefactor to angle to diminish it in proportion to half the $angle so it the top of the shadow looks more realistic
  656. ht=`convert xc: -format "%[fx:round($ff*($hr+$wr*tan($aleft*(1+$angle*(pi/360)))))]" info:`
  657. tx=0
  658. ty=$ht
  659. wd=`convert xc: -format "%[fx:round($ff*$wr)]" info:`
  660. # echo "aleft=$aleft; aright=$aright; bx=$bx; by=$by; mx=$mx; my=$my; ht=$ht; wd=$wd; tx=$tx; ty=$ty"
  661.  
  662. # set up page offsets for merging
  663. # compute xshift to partially take into account the penumbra blurring, fudge in proportion to $angle
  664. xshift=`convert xc: -format "%[fx:round(min(1.5,(-$angle/30))*$penumbra/tan($aright))]" info:`
  665. # adjust mx for xshift
  666. mx=$((mx+xshift))
  667. xoff=`echo "$xyoffset" | cut -d, -f 1`
  668. yoff=`echo "$xyoffset" | cut -d, -f 2`
  669. if [ "$im_version" -ge "06080400" ]; then
  670. pagesx=$((wl+wr-penumbra2+1-xshift+xoff))
  671. pagesy=$((hh-ht-hr+yoff-2))
  672. penumbra=$((penumbra+1))
  673. else
  674. pagesx=$((wl+wr-penumbra2-4-xshift+xoff))
  675. pagesy=$((hh-ht-hr+yoff))
  676. fi
  677. pageax=0
  678. pageay=0
  679. pageshadow=`printf "%+d%+d" ${pagesx} ${pagesy}`
  680. pageimage=`printf "%+d%+d" ${pageax} ${pageay}`
  681. # echo "pagesx=$pagesx; pagesy=$pagesy; pageax=$pageax; pageay=$pageay;"
  682.  
  683. elif [ $sign -eq 1 ]; then
  684. # shadow on left side
  685. bx=`convert xc: -format "%[fx:round($ff*$wl)]" info:`
  686. by=0
  687. mx=0
  688. my=`convert xc: -format "%[fx:round($ff*$hl)]" info:`
  689. # add fudgefactor to angle to diminish it in proportion to half the $angle so it the top of the shadow looks more realistic
  690. ht=`convert xc: -format "%[fx:round($ff*($hl+$wl*tan($aright*(1-$angle*(pi/360)))))]" info:`
  691. tx=`convert xc: -format "%[fx:round($ff*$wl)]" info:`
  692. ty=$ht
  693. wd=$tx
  694. # echo "aleft=$aleft; aright=$aright; bx=$bx; by=$by; mx=$mx; my=$my; ht=$ht; wd=$wd; tx=$tx; ty=$ty"
  695.  
  696. # set up page offsets for merging
  697. # compute xshift to partially take into account the penumbra blurring, fudge in proportion to $angle
  698. xshift=`convert xc: -format "%[fx:round(min(1.5,($angle/30))*$penumbra/tan($aleft))]" info:`
  699. # adjust bx and tx for xshift
  700. bx=$((bx+xshift))
  701. tx=$((tx+xshift))
  702. xoff=`echo "$xyoffset" | cut -d, -f 1`
  703. yoff=`echo "$xyoffset" | cut -d, -f 2`
  704. if [ "$im_version" -ge "06080400" ]; then
  705. pageax=$((tx-2-xshift-xoff+6))
  706. pageay=$((-yoff))
  707. penumbra=$((penumbra+1))
  708. else
  709. pageax=$((tx-2-xshift-xoff))
  710. pageay=$((-yoff))
  711. fi
  712. pagesx=0
  713. pagesy=$((hh-ht-hl))
  714. pageshadow=`printf "%+d%+d" ${pagesx} ${pagesy}`
  715. pageimage=`printf "%+d%+d" ${pageax} ${pageay}`
  716. # echo "pagesx=$pagesx; pagesy=$pagesy; pageax=$pageax; pageay=$pageay;"
  717. fi
  718.  
  719. # draw shadow triangle
  720. convert -size $((wd+$xshift))x${ht} xc:"rgba(255,255,255,0)" -fill "gray($umbra%)" \
  721. -draw "polygon $bx,$by $mx,$my $tx,$ty" -flip \
  722. -channel rgba -bordercolor "rgba(255,255,255,0)" -border ${penumbra} \
  723. -background "rgba(255,255,255,0)" -alpha background -blur ${penumbra}x65000 \
  724. -level 0x100% -gravity south +repage $tmpS1
  725.  
  726. # merge shadow and image and background color
  727. # echo "wl=$wl; hh=$hh; hl=$hl; pagesx=$pagesx; pagesy=$pagesy; pageax=$pageax; pageay=$pageay"
  728. convert $setcspace -page $pageshadow $tmpS1 \
  729. -page $pageimage $tmpA1 \
  730. -background none -layers merge +repage $coloring -fuzz $fuzzval% -trim +repage $outfile
  731.  
  732. fi
  733.  
  734. exit 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement