fork download
  1. #!/bin/bash
  2. # your code goes here
  3. #!/bin/bash
  4. #
  5. # Developed by Fred Weinhaus revised 6/9/2012 .......... revised 4/25/2015
  6. #
  7. # ------------------------------------------------------------------------------
  8. #
  9. # Licensing:
  10. #
  11. # Copyright © Fred Weinhaus
  12. #
  13. # My scripts are available free of charge for non-commercial use, ONLY.
  14. #
  15. # For use of my scripts in commercial (for-profit) environments or
  16. # non-free applications, please contact me (Fred Weinhaus) for
  17. # licensing arrangements. My email address is fmw at alink dot net.
  18. #
  19. # If you: 1) redistribute, 2) incorporate any of these scripts into other
  20. # free applications or 3) reprogram them in another scripting language,
  21. # then you must contact me for permission, especially if the result might
  22. # be used in a commercial or for-profit environment.
  23. #
  24. # My scripts are also subject, in a subordinate manner, to the ImageMagick
  25. # license, which can be found at: http://w...content-available-to-author-only...k.org/script/license.php
  26. #
  27. # ------------------------------------------------------------------------------
  28. #
  29. ####
  30. #
  31. # USAGE: overlapcrop [-s size] [-o overlap] [-m mode] [-u]
  32. # [-i initnum] [-z zeropad] [-d delay] [-l loop] [-c canvas]
  33. # [-M] [-L] [-F frame] [-S spacing] [-R] infile outfile
  34. # USAGE: overlapcrop [-h or -help]
  35. #
  36. # OPTIONS:
  37. #
  38. # -s size crop subsection dimensions in pixels; one or two
  39. # integers>0 with "x" separator; default=128x128
  40. # -o overlap overlap of subsections; pixels or percent
  41. # as one or two integers with "x" separator;
  42. # if percent sign included, then it will be converted to
  43. # pixels in range 0<=integer<subsection size;
  44. # default="50%x50%"
  45. # -m mode mode of output; choices are matrix (numbered),
  46. # sequential (numbered), frames or animation;
  47. # default=matrix
  48. # -u (uniform) flag to keep only same size crop sections and discard
  49. # smaller pieces on the right and bottom; default is to
  50. # keep all crop pieces
  51. # -i initnum initial number for output naming; integer>=0; default=1
  52. # -z zeropad number of digits with zero padding for sequential mode;
  53. # integer>=0; default=0 (no zero padding)
  54. # -d delay delay for animation mode; integer>=0; default=50
  55. # -l loop number of loops for animation mode; integer>=0;
  56. # default=0 (endless looping)
  57. # -c (canvas) leave the virtual canvas in the meta data for the images;
  58. # default is to remove the virtual canvas
  59. # -M (montage) create single montage image; applicable only to matrix
  60. # or sequential mode; default is no montage
  61. # -L (label) flag to add filename labels to each image in the montage;
  62. # default is no filename labels
  63. # -F frame frame size around each image in the montage; integers>=0;
  64. # default=5
  65. # -S spacing spacing between images in the montage; integers>=0;
  66. # default=0
  67. # -R (remove) flag to remove/delete all individual images generated
  68. # prior to creating the montage. Default is leave
  69. # all individual images.
  70. #
  71. ###
  72. #
  73. # NAME: OVERLAPCROP
  74. #
  75. # PURPOSE: To create a sequence of cropped subsections permitting optional
  76. # overlap of the subsections.
  77. #
  78. # DESCRIPTION: OVERLAPCROP creates a sequence of cropped subsections permitting
  79. # optional overlap of the subsections. The output images may be numbered either
  80. # sequentially or in matrix mode (column and row). The images may also be
  81. # output to a single file with multiple frames, to an animation or to a
  82. # montage.
  83. #
  84. # OPTIONS:
  85. #
  86. # -s size ... SIZE is the crop subsection WidthxHeight dimensions in pixels.
  87. # Either one or two non-negative integers may be used with "x" separator if two.
  88. # If only one is provided (with no separator), then it will be used for both
  89. # width and height. The default="128x128".
  90. #
  91. # -o overlap ... OVERLAP is the amount of overlap of subsections. Overlap may
  92. # be specified as pixels or percent of subsection size. Values are either one
  93. # or two non-negative integers with "x" separator. If a percent sign is
  94. # included, then the overlap will be converted to pixels. Values must be
  95. # specified (or convert) in the range of zero to the subsection size. The
  96. # default="50%x50%".
  97. #
  98. # -m mode ... MODE of the output. Choices are matrix (numbered) or m,
  99. # sequential (numbered) or s, frames (mode) or f and animation (mode) or a.
  100. # The default=matrix.
  101. #
  102. # -u (uniform) ... Flag to keep only same size crop sections and discard
  103. # smaller pieces on the right and bottom. The default is to keep all pieces.
  104. #
  105. # -i initnum ... INITNUM is the initial (starting) number for output naming.
  106. # Values are non-negative integers. The default=1.
  107. #
  108. # -z zeropad ... ZEROPAD is the number of digits with zero padding for
  109. # numbering the output images in sequential mode. Values are non-negative
  110. # integers. The default=0 (no zero padding).
  111. #
  112. # -d delay ... DELAY for animation mode. Values are non-negative integers. The
  113. # default=50.
  114. #
  115. # -l loop ... LOOP is the number of times to loop the animation. Values are
  116. # non-negative integers. The default=0 (endless looping).
  117. #
  118. # -c (canvas) ... Flag to leave the virtual canvas in the meta data for the
  119. # images. This is useful when making an animation so that the subsections keep
  120. # their position relative to the original image. The default is to remove the
  121. # virtual canvas, which then just has each frame of the animation replacing the
  122. # previous one.
  123. #
  124. # -M (montage) ... Flag to create a single montage image for matrix or
  125. # sequential modes only. The default is no montage.
  126. #
  127. # -L (label) ... Flag to add filename labels to each image in the montage.
  128. # The default is no filename labels.
  129. #
  130. # -F frame ... FRAME is the size of the frame-like border in pixels placed
  131. # around each image in the montage. Values are non-negative integers.
  132. # The default=5.
  133. #
  134. # -S spacing ... SPACING is the amount of space in pixels to put between each
  135. # images in the montage. Values are non-negative integers. The default=0.
  136. #
  137. # -R (remove) ... Flag to remove/delete all individual images generated
  138. # prior to creating the montage. Th default is to leave all individual images,
  139. # i.e, no deletion.
  140. #
  141. # CAVEAT: No guarantee that this script will work on all platforms,
  142. # nor that trapping of inconsistent parameters is complete and
  143. # foolproof. Use At Your Own Risk.
  144. #
  145. ######
  146. #
  147.  
  148. # set default values
  149. size="128x128"
  150. overlap="50%x50%" # percent or pixels, must not be 100% or size of subsection
  151. mode="matrix" # matrix or sequential or frames or animation
  152. uniform="no" # uniform size only, skip small sections at right and bottom; yes or no
  153. initnum=1 # initial number for sequential or matrix mode; integer>=0
  154. zeropad=0 # number of digits with zero padding for sequential mode; integer>=0
  155. delay=50 # delay for animation mode; integer>=0
  156. loop=0 # looping for animation mode; integer>=0
  157. canvas="off" # on or off to keep virtual canvas; on is useful for animation
  158. montage="no" # montage images, applicable only to matrix or sequential mode
  159. label="no" # montage label with filename; yes or no
  160. frame=5 # montage frame size in pixels; integer>=0
  161. spacing=0 # montage spacing in pixels; integer>=0
  162. remove="no" # remove individual images if montage
  163.  
  164. echo "1"
  165.  
  166. # set directory for temporary files
  167. dir="." # suggestions are dir="." or dir="/tmp"
  168.  
  169. echo "2"
  170.  
  171. # set up functions to report Usage and Usage with Description
  172. PROGNAME=`type $0 | awk '{print $3}'` # search for executable on path
  173. PROGDIR=`dirname $PROGNAME` # extract directory of program
  174. PROGNAME=`basename $PROGNAME` # base name of program
  175. usage1()
  176. {
  177. echo >&2 ""
  178. echo >&2 "$PROGNAME:" "$@"
  179. sed >&2 -e '1,/^####/d; /^###/g; /^#/!q; s/^#//; s/^ //; 4,$p' "$PROGDIR/$PROGNAME"
  180. }
  181. usage2()
  182. {
  183. echo >&2 ""
  184. echo >&2 "$PROGNAME:" "$@"
  185. sed >&2 -e '1,/^####/d; /^######/g; /^#/!q; s/^#*//; s/^ //; 4,$p' "$PROGDIR/$PROGNAME"
  186. }
  187.  
  188. echo "3"
  189.  
  190. # function to report error messages
  191. errMsg()
  192. {
  193. echo ""
  194. echo $1
  195. echo ""
  196. usage1
  197. exit 1
  198. }
  199.  
  200. echo "4"
  201.  
  202. # function to test for minus at start of value of second part of option 1 or 2
  203. checkMinus()
  204. {
  205. test=`echo "$1" | grep -c '^-.*$'` # returns 1 if match; 0 otherwise
  206. [ $test -eq 1 ] && errMsg "$errorMsg"
  207. }
  208.  
  209. echo "5"
  210.  
  211. # test for correct number of arguments and get values
  212. if [ $# -eq 0 ]
  213. then
  214. # help information
  215. echo ""
  216. usage2
  217. exit 0
  218. elif [ $# -gt 24 ]
  219. then
  220. errMsg "--- TOO MANY ARGUMENTS WERE PROVIDED ---"
  221. else
  222. while [ $# -gt 0 ]
  223. do
  224. # get parameter values
  225. case "$1" in
  226. -h|-help) # help information
  227. echo ""
  228. usage2
  229. exit 0
  230. ;;
  231. -s) # get size
  232. shift # to get the next parameter
  233. # test if parameter starts with minus sign
  234. errorMsg="--- INVALID SIZE SPECIFICATION ---"
  235. checkMinus "$1"
  236. size=`expr "$1" : '\([0-9]*x*[0-9]*\)'`
  237. [ "$size" = "" ] && errMsg "--- SIZE=$size MUST BE ONE OR TWO x SEPARATED NON-NEGATIVE INTEGERS ---"
  238. ;;
  239. -o) # get overlap
  240. shift # to get the next parameter
  241. # test if parameter starts with minus sign
  242. errorMsg="--- INVALID OVERLAP SPECIFICATION ---"
  243. checkMinus "$1"
  244. overlap=`expr "$1" : '\([0-9]*%*x*[0-9]*%*\)'`
  245. [ "$overlap" = "" ] && errMsg "--- OVERLAP=$overlap MUST BE ONE OR TWO x SEPARATED NON-NEGATIVE INTEGERS ---"
  246. ;;
  247. -m) # get mode
  248. shift # to get the next parameter
  249. # test if parameter starts with minus sign
  250. errorMsg="--- INVALID MODE SPECIFICATION ---"
  251. checkMinus "$1"
  252. mode=`echo "$1" | tr "[:upper:]" "[:lower:]"`
  253. case "$mode" in
  254. matrix|m) mode="matrix" ;;
  255. sequential|s) mode="sequential" ;;
  256. frames|f) mode="frames" ;;
  257. animation|a) mode="animation" ;;
  258. *) errMsg "--- MODE=$mode IS AN INVALID VALUE ---"
  259. esac
  260. ;;
  261. -u) # set uniform
  262. uniform="yes"
  263. ;;
  264. -i) # get initnum
  265. shift # to get the next parameter
  266. # test if parameter starts with minus sign
  267. errorMsg="--- INVALID INITNUM SPECIFICATION ---"
  268. checkMinus "$1"
  269. initnum=`expr "$1" : '\([0-9]*\)'`
  270. [ "$initnum" = "" ] && errMsg "--- INITNUM=$initnum MUST BE A NON-NEGATIVE INTEGER ---"
  271. ;;
  272. -z) # get zeropad
  273. shift # to get the next parameter
  274. # test if parameter starts with minus sign
  275. errorMsg="--- INVALID ZEROPAD SPECIFICATION ---"
  276. checkMinus "$1"
  277. zeropad=`expr "$1" : '\([0-9]*\)'`
  278. [ "$zeropad" = "" ] && errMsg "--- ZEROPAD=$zeropad MUST BE A NON-NEGATIVE INTEGER ---"
  279. ;;
  280. -d) # get delay
  281. shift # to get the next parameter
  282. # test if parameter starts with minus sign
  283. errorMsg="--- INVALID DELAY SPECIFICATION ---"
  284. checkMinus "$1"
  285. delay=`expr "$1" : '\([0-9]*\)'`
  286. [ "$delay" = "" ] && errMsg "--- DELAY=$delay MUST BE A NON-NEGATIVE INTEGER ---"
  287. ;;
  288. -l) # get loop
  289. shift # to get the next parameter
  290. # test if parameter starts with minus sign
  291. errorMsg="--- INVALID LOOP SPECIFICATION ---"
  292. checkMinus "$1"
  293. loop=`expr "$1" : '\([0-9]*\)'`
  294. [ "$loop" = "" ] && errMsg "--- LOOP=$loop MUST BE A NON-NEGATIVE INTEGER ---"
  295. ;;
  296. -c) # set canvas
  297. canvas="on"
  298. ;;
  299. -M) # set montage
  300. montage="yes"
  301. ;;
  302. -L) # set label
  303. label="yes"
  304. ;;
  305. -F) # get frame
  306. shift # to get the next parameter
  307. # test if parameter starts with minus sign
  308. errorMsg="--- INVALID FRAME SPECIFICATION ---"
  309. checkMinus "$1"
  310. frame=`expr "$1" : '\([0-9]*\)'`
  311. [ "$frame" = "" ] && errMsg "--- FRAME=$frame MUST BE A NON-NEGATIVE INTEGER ---"
  312. ;;
  313. -S) # get spacing
  314. shift # to get the next parameter
  315. # test if parameter starts with minus sign
  316. errorMsg="--- INVALID SPACING SPECIFICATION ---"
  317. checkMinus "$1"
  318. spacing=`expr "$1" : '\([0-9]*\)'`
  319. [ "$spacing" = "" ] && errMsg "--- SPACING=$spacing MUST BE A NON-NEGATIVE INTEGER ---"
  320. ;;
  321. -R) # set remove
  322. remove="yes"
  323. ;;
  324. -) # STDIN and end of arguments
  325. break
  326. ;;
  327. -*) # any other - argument
  328. errMsg "--- UNKNOWN OPTION ---"
  329. ;;
  330. *) # end of arguments
  331. break
  332. ;;
  333. esac
  334. shift # next option
  335. done
  336. #
  337. # get infile and outfile
  338. infile="$1"
  339. outfile="$2"
  340. fi
  341.  
  342. echo "6"
  343.  
  344. # test that infile provided
  345. [ "$infile" = "" ] && errMsg "NO INPUT FILE SPECIFIED"
  346.  
  347. # test that outfile provided
  348. [ "$outfile" = "" ] && errMsg "NO OUTPUT FILE SPECIFIED"
  349.  
  350. outname=`echo "$outfile" | sed -n 's/^\(.*\)[\.].*$/\1/p'`
  351. suffix=`echo "$outfile" | sed -n 's/^.*[\.]\(.*\)$/\1/p'`
  352.  
  353. sfx=`echo "$suffix" | tr "[:upper:]" "[:lower:]"`
  354. if [ "$mode" = "animation" -a "$sfx" != "gif" -a "$sfx" != "miff" ]; then
  355. errMsg "--- ANIMATION REQUIRES SUFFIX OF GIF OR MIFF ---"
  356. fi
  357.  
  358. # setup temporary images
  359. tmpA1="$dir/overlapcrop_A_$$.mpc"
  360. tmpA2="$dir/overlapcrop_A_$$.cache"
  361. tmp1="$dir/overlapcrop_1_$$.miff"
  362. trap "rm -f $tmpA1 $tmpA2 $tmp1;" 0
  363. trap "rm -f $tmpA1 $tmpA2 $tmp1; exit 1" 1 2 3 15
  364. trap "rm -f $tmpA1 $tmpA2 $tmp1; exit 1" ERR
  365.  
  366. # read the input image and filter image into the temp files and test validity.
  367. convert -quiet "$infile" $gray +repage "$tmpA1" ||
  368. errMsg "--- FILE $infile DOES NOT EXIST OR IS NOT AN ORDINARY FILE, NOT READABLE OR HAS ZERO SIZE ---"
  369.  
  370. echo "7"
  371.  
  372. # get width and height of image
  373. ww=`identify -ping -format "%w" $tmpA1`
  374. hh=`identify -ping -format "%h" $tmpA1`
  375.  
  376. # get width and height of subsection
  377. sw=`echo "${size}" | cut -dx -f1`
  378. sh=`echo "${size}" | cut -dx -f2`
  379. #echo "sw=$sw; sh=$sh"
  380.  
  381. # test that subsection smaller than image
  382. [ $sw -ge $ww -o $sh -ge $hh ] && errMsg "--- SUBSECTION SIZE MUST BE SMALLER THAN INFILE SIZE ---"
  383.  
  384. echo "8"
  385. # get offset amount in pixels for subsection taking into account overlap
  386. test=`echo "$overlap" | grep "%"`
  387. #echo "test=$test"
  388. if [ "$test" = "" ]; then
  389. # overlap in pixels
  390. ox=`echo "${overlap}" | cut -dx -f1`
  391. oy=`echo "${overlap}" | cut -dx -f2`
  392. else
  393. # overlap in percent
  394. overlap=`echo "$overlap" | sed 's/%//g'`
  395. ox=`echo "${overlap}" | cut -dx -f1`
  396. oy=`echo "${overlap}" | cut -dx -f2`
  397. # convert to pixels
  398. ox=`convert xc: -format "%[fx:floor($ox*$sw/100)]" info:`
  399. oy=`convert xc: -format "%[fx:floor($oy*$sh/100)]" info:`
  400. fi
  401. ow=`convert xc: -format "%[fx:$sw-$ox]" info:`
  402. oh=`convert xc: -format "%[fx:$sh-$oy]" info:`
  403.  
  404. # test if overlap is sw or sh
  405. [ $ox -eq $sw ] && errMsg "--- X OVERLAP CANNOT EQUAL THE WIDTH OF THE SUBSECTION ---"
  406. [ $oy -eq $sh ] && errMsg "--- Y OVERLAP CANNOT EQUAL THE HEIGHT OF THE SUBSECTION ---"
  407.  
  408. echo "9"
  409. # get ending pixel for stopping loops
  410. if [ "$uniform" = "no" ]; then
  411. ew=`convert xc: -format "%[fx:$ww-$sw+$ox-1]" info:`
  412. eh=`convert xc: -format "%[fx:$hh-$sh+$oy-1]" info:`
  413. elif [ "$uniform" = "yes" ]; then
  414. ew=`convert xc: -format "%[fx:$ww-$sw]" info:`
  415. eh=`convert xc: -format "%[fx:$hh-$sh]" info:`
  416. fi
  417. echo "9.1"
  418. #echo "ww=$ww; hh=$hh; sw=$sw; sh=$sh; ow=$ow; oh=$oh; ew=$ew; eh=$eh"
  419.  
  420. # set up to keep virtual canvas
  421. if [ "$canvas" = "off" ]; then
  422. repaging="+repage"
  423. else
  424. repaging=""
  425. fi
  426. echo "9.2"
  427. # compute number of sections
  428. k=0
  429. for ((i=0;i<=eh;i+=oh)); do
  430. for ((j=0;j<=ew;j+=ow)); do
  431. ((k++))
  432. done
  433. done
  434. num=$k
  435.  
  436. echo "10"
  437.  
  438. echo "mode=$mode"
  439.  
  440. if [ "$mode" = "frames" -o "$mode" = "animation" ]; then
  441. convert -size $size xc: $tmp1
  442. fi
  443.  
  444. echo ""
  445. # process subsections
  446. filelist=""
  447. t=1
  448. k=$initnum
  449. m=$initnum
  450. dh=0
  451. for ((i=0;i<=eh;i+=oh)); do
  452. dw=0
  453. n=$initnum
  454. for ((j=0;j<=ew;j+=ow)); do
  455. echo "Subsection: $t out of $num (${sw}x${sh}+${dw}+${dh}) row=$m col=$n"
  456. if [ "$mode" = "frames" ]; then
  457. convert $tmpA1[${sw}x${sh}+${dw}+${dh}] $repaging miff:- | convert $tmp1 - $tmp1
  458. elif [ "$mode" = "animation" ]; then
  459. convert $tmpA1[${sw}x${sh}+${dw}+${dh}] $repaging miff:- | convert $tmp1 - $tmp1
  460. elif [ "$mode" = "sequential" ]; then
  461. kk=`printf "%0${zeropad}d" $k`
  462. convert $tmpA1[${sw}x${sh}+${dw}+${dh}] $repaging ${outname}_$kk.$suffix
  463. filelist="$filelist ${outname}_$kk.$suffix"
  464. elif [ "$mode" = "matrix" ]; then
  465. convert $tmpA1[${sw}x${sh}+${dw}+${dh}] $repaging ${outname}_r${m}_c${n}.$suffix
  466. filelist="$filelist ${outname}_r${m}_c${n}.$suffix"
  467. fi
  468. dw=$(($dw+$ow))
  469. ((t++))
  470. ((k++))
  471. ((n++))
  472. done
  473. dh=$(($dh+$oh))
  474. ((m++))
  475. done
  476. echo ""
  477.  
  478. echo "11"
  479.  
  480. if [ "$mode" = "frames" ]; then
  481. convert $tmp1 -delete 0 ${outname}.$suffix
  482. elif [ "$mode" = "animation" ]; then
  483. convert -delay $delay -dispose Background $tmp1 -delete 0 -loop $loop "${outname}_animation.$suffix"
  484. fi
  485.  
  486. echo "12"
  487.  
  488. if [ "$mode" != "frames" -a "$mode" != "animation" -a "$montage" = "yes" ]; then
  489. if [ "$label" = "yes" ]; then
  490. labeling="-label %t"
  491. else
  492. labeling=""
  493. fi
  494. montage $labeling $filelist -tile $((n-initnum))x$((m-initnum)) \
  495. -frame $frame -geometry +${spacing}+${spacing} \
  496. "${outname}_montage.$suffix"
  497. if [ "$remove" = "yes" ]; then
  498. rm $filelist
  499. fi
  500. fi
  501.  
  502. echo "13"
  503.  
  504. exit 0
  505.  
  506.  
Success #stdin #stdout #stderr 0s 5880KB
stdin
Standard input is empty
stdout
1
2
3
4
5

stderr
./prog.sh: line 172: type: ./prog.sh: not found
dirname: missing operand
Try 'dirname --help' for more information.
basename: missing operand
Try 'basename --help' for more information.

:
sed: read error on /: Is a directory