Thursday, June 21, 2012

[Bash] png2pdf: convert png files into a single pdf file

Download link
#!/bin/bash
# to convert png files into a single pdf file using pdflatex
# usage:
#           png2pdf.sh png-file[s] -o png2pdf.pdf -nC nCol -nR nRow
# e.g.,
#          Given 12 png files (one for each month) with a name like "ssh_??.png",
#          to create a 3-pages pdf file with 2 by 2 on each page,
#          and a caption like "Fiugre* Sea Surface Height \\ ??; ?? \\ ??; ??"
#          where \\ means line break and ?? is the month-tag in original png filename.
#          you can run,
#            png2pdf.sh -o ssh_monthly.pdf -nC 2 -nR 2 ssh_??.png -title 'Sea Surface Height' -ns 5 -ne 6
#                               [ here -ns: start-index of characters for the caption; -ne: end-index]
#          or
#           png2pdf.sh -o ssh_monthly.pdf -nC 2 -nR 2 ssh_??.png -title 'Sea Surface Height' -sep '_' 2
#                               [-sep: field seperator, 2 is the No. of field used for the caption]
#
#         http://scriptdemo.blogspot.com

fixCaption()
{
    echo $* | sed -e 's@_@--@g'
}

nfile=0
isPDFname=0
isnCol=0
isnRow=0
isDel=0
isCaption=0
isSep=0
isDebug=0


[ $# -eq 0 ] && sed -n '3,17p' `which png2pdf.sh` && exit

while test -n "$1"
do
  case "$1" in
    -nC|-nc|-nCol|-ncol|-Ncol)
       nCol=$2
       isnCol=1
       shift
       shift
       ;;
    -nR|-nr|-nRow|-Nrow|-nrow)
       nRow=$2
       isnRow=1
       shift
       shift
       ;;
    -title|-Title|-Caption|-caption|-c)
       myCaption=$2
       isCaption=1
       shift
       shift
       ;;
    -sep|-Sep|-seperator)
       mysep=$2
       mynf=$3
       isSep=1
       isCaption=1
       shift;
       shift;
       ;;
    -ns|-NS|-CS|-cs)
       cstart=$2
       isCaption=1
       shift
       shift
       ;;
    -ne|-NE|-CE|-ce)
       cend=$2
       isCaption=1
       shift
       shift
       ;;
    -d|-delete|-del|-D)
       isDel=1;
       shift
       ;;
    -debug|-Debug)
       isDebug=1
       shift
       ;;
    -o|-O)
       pdfname=$2
       isPDFname=1
       shift
       shift
       ;;
     *)
       sufstr=`echo $1 | awk -F. '{print $2}'`
       if [ ${#sufstr} -eq 0 ]; then
          tmpfile="$1".png
          if [ -f ${tmpfile} ]; then
             imgfile[$nfile]=${tmpfile}
             nfile=`expr $nfile + 1`
          fi
       elif [ -f $1 ]; then
          if [ -f $1 ]; then
             imgfile[$nfile]=$1
             nfile=`expr $nfile + 1`
          fi
       fi
       shift
       ;;
  esac
done
if [ ${isnRow} -eq 0 ] && [ ${isnCol} -eq 0 ]; then
   nCol=1
   nRow=1
   nPage=${nfile}
elif [ ${isnCol} -eq 1 ] && [ ${isnRow} -eq 0 ]; then
   nRow=`echo "${nfile}/${nCol}" | bc -l | awk '{ if ($1 == int($1)) {printf "%d\n", $1} else { if ($1>0) {printf "%d\n",int($1)+1 } else {printf "%d\n",int($1)} } }'`
   nPage=1
elif [ ${isnRow} -eq 1 ] & [ ${isnCol} -eq 0 ]; then
   nCol=`echo "${nfile}/${nRow}" | bc -l | awk '{ if ($1 == int($1)) {printf "%d\n", $1} else { if ($1>0) {printf "%d\n",int($1)+1 } else {printf "%d\n",int($1)} } }'`
   nPage=1
else
   nPage=`echo "${nfile}/${nRow}/${nCol}" | bc -l | awk '{ if ($1 == int($1)) {printf "%d\n", $1} else { if ($1>0) {printf "%d\n",int($1)+1 } else {printf "%d\n",int($1)} } }'`
fi
if [ ${isCaption} -eq 1 ]; then
   if [ ${#cend} -ne 0 ] & [ ${#cstart} -eq 0 ]; then
      cstart=1
   fi
fi
colstr=`printf "%*s\n" ${nCol} " " | sed -e 's/\ /c/g'`
nwidth=$(printf "%.2f\n" `echo "1/${nCol}" | bc -l`)

[ ${nwidth} == "1.00" ] && nwidth=""
[ ${isDebug} -eq 1 ] && echo -e "nCol=${nCol}\nnRow=${nRow}\nnWid=${nwidth}\nnPage=${nPage}"

# header of tex file
[ ${isPDFname} -eq 0 ] && pdfname="png2pdf.pdf"
texfile=${pdfname%.*}.tex
[ -e ${texfile} ] && mv ${texfile} old_${texfile}
touch ${texfile}

echo '\documentclass[letterpaper,12pt]{article}' >> ${texfile}
echo '\usepackage{graphicx}' >> ${texfile}
[ ${isCaption} -eq 1 ] && echo '\usepackage{caption}' >> ${texfile}
echo '\begin{document}' >> ${texfile}

for (( np=0; np<${nPage}; np++ ))
do
    echo '\thispagestyle{empty}' >> ${texfile}
    echo '\begin{figure}' >> ${texfile}
    echo '\centering' >> ${texfile}
    echo "\begin{tabular}{${colstr}}" >> ${texfile}

    ns=`expr ${np} \* ${nCol} \* ${nRow}`
    if [ ${isCaption} -eq 1 ] && [ ${#myCaption} -ne 0 ]; then
       if [ ${#cstart} -ne 0 ] || [ ${#cend} -ne 0 ]; then
          tmpCaption="${myCaption} \protect \\\\"
       else
          tmpCaption="${myCaption}"
       fi
    else
       tmpCaption=""
    fi
    for (( nL=0; nL<${nRow}; nL++ ))
    do
       nss=`expr ${ns} + ${nCol} \* ${nL}`
       for (( nC=0; nC<${nCol}; nC++ ))
       do
           nfig=`expr ${nss} + ${nC}`
           if [ ${nfig} -lt ${nfile} ]; then
              imgname=${imgfile[$nfig]}
              if [ ${nC} -eq `expr ${nCol} - 1` ]; then
                 if [ ${nL} -eq `expr ${nRow} - 1` ]; then
                    tmpstr=""
                 else
                    tmpstr=" \\\\"
                 fi
              else
                 tmpstr=" &"
              fi

              if [ ${nL} -eq `expr ${nRow} - 1` ] && [ ${nC} -eq `expr ${nCol} - 1` ]; then
                 tmpstr=""
              fi
              [ ${nfig} -eq `expr ${nfile} - 1` ] && tmpstr=""
              if [ ${isCaption} -eq 1 ]; then
                 if [ ${isSep} -eq 0 ]; then
                    if [ ${#cend} -eq 0 ]; then
                       subfn=`echo ${imgname} | cut -c${cstart}-`
                    else
                       subfn=`echo ${imgname} | cut -c${cstart}-${cend}`
                    fi
                 else
                    subfn=`echo ${imgname} | cut -d${mysep} -f${mynf}`
                    #echo "${imgname} "sep="${mysep} nf=${mynf} ==> ${subfn}"
                 fi
                 if [ ${#subfn} -ne 0 ]; then
                    [ "${tmpstr}" == "" ] && tmpCaption="${tmpCaption}${subfn}"
                    [ "${tmpstr}" == " \\\\" ] && tmpCaption="${tmpCaption}${subfn} \protect \\\\ "
                    [ "${tmpstr}" == " &" ] && tmpCaption="${tmpCaption}${subfn}; "
                 fi
              fi
              echo "\includegraphics[width=${nwidth}\linewidth]{${imgname}} ${tmpstr}" >> ${texfile}
           fi
       done
    done
    echo "\end{tabular}" >> ${texfile}
    if [ ${isCaption} -eq 1 ]; then
       tmpCaption=`fixCaption ${tmpCaption}`
       echo "\caption{${tmpCaption}}" >> ${texfile}
    fi
    echo "\end{figure}" >> ${texfile}
    [ ${np} -lt `expr ${nPage} - 1` ] && echo "\clearpage" >> ${texfile}
done

echo "\end{document}" >> ${texfile}
[ ! -f ${texfile} ] && echo "failed to create tex file ==> exit" && exit

#compile the tex file
logfile=${pdfname%.*}.log
auxfile=${pdfname%.*}.aux
if [ ${isDebug} -eq 1 ]; then
   pdflatex ${texfile}
else
   pdflatex -interaction=batchmode ${texfile} 1>/dev/null
fi
[ -f ${logfile} ] && rm -f ${logfile}
[ -f ${auxfile} ] && rm -f ${auxfile}
[ ${isDel} -eq 1 ] && rm -f ${texfile}

Wednesday, June 6, 2012

[Bash] ps2png: convert ps to png format with high quality

previous solution using ImageMagicK works too, but may not produce the high quality expected.

#!/bin/bash
# convert a single-page ps file into png format using gs
# usage:
#            ps2png psfile.ps
# Note:
#           1: need gs installed
#           2: same name is used for the png file
#           http://scriptdemo.blogspot.com

if [ $# == 0 ]; then
   sed -n '2,4p' `which ps2png`
   exit
else
  for psname in $*
  do
     if [ -e $psname ]; then
        pngname=`echo ${psname%%.*}`
          gs -r300 -dTextAlphaBits=4 -sDEVICE=png16m -sOutputFile=${pngname}.png -dBATCH -dNOPAUSE ${psname}
     else
        echo "${psname} does not exist!"
     fi
  done
fi

ShowCalendar