Resize รูปด้วย Shell script แบบมี GUI

ขอเขียนลงห้องทดลองด้วยคนนะครับ :D

Shell script อันนี้เขียนไว้นานแล้วครับ (ประมาณ 2 ปีแล้ว :P) ให้ทำการ resize รูป JPEG ด้วยคำสั่ง convert จาก ImageMagick แล้วช่วงนั้นก็อยากเขียน shell script ให้มี GUI ก็เลยใช้ Xdialog ในการสร้าง GUI ขึ้นมา แต่ตอนนั้นสคริปต์มีข้อจำกัดนิดหน่อย คือทำงานกับชื่อแฟ้มหรือไดเร็คทอรีที่มี space ไม่ได้ โค้ดก็ไม่สวย :P (ตอนนั้นยังรู้อะไรไม่ค่อยมากนัก จริงๆ มันไม่ได้มีอะไรใหม่หรอก)

วันนี้มีเหตุให้ต้องมานั่ง resize ภาพประมาณ 200 กว่าภาพได้ เลยได้ฤกษ์ขุดขึ้นมาลองใช้ดูหน่อย แล้วก็นั่งแก้ไปแก้มา ก็แก้ให้ข้อจำกัดเหล่านั้นหมดไปแล้วเลยมาเสนอที่นี่ดีกว่า สคริปต์นี้ต้องการ ImageMagick กับ Xdialog ถึงจะทำงานนะครับ ใครใช้ *buntu ก็คง apt-get ได้เลย

ถ้าดูแล้วมีตรงไหนน่าแก้ไขก็แก้ได้เลยนะครับ

คำอธิบายทั้งหลายก็พยายามเขียนเอาไว้ใน comment ของ code ไว้แล้ว

#!/bin/bash


#jpgresize shell script with Xdialog.
#This program depends on ImageMagick (convert), Xdialog, textutils, expr and bc

#variables
tempfile=`mktemp`

#======================================================================

#functions
# numfiles -> it gets number of files to calculate the percentage.
# setcount -> This function sets the variables, named COUNT2 and COUNT3, to calculate the percentage. COUNT4 is for use with --gauge option.
# Xresize -> This function resizes the jpg and JPG files and displays progress bar using COUNT4 value.
# prog_term -> terminate the program.
# help_me -> display help.
# version -> display version.
# wizard_start -> start the wizard.
# choose_dir_wiz -> This function chooses a directory and keep the value into $tempfile.
# get_dir -> This function gets the value of a directory that will be used to keep the resized files. 
# get_size -> it gets the size (using slide bar) to work with convert. 

numfiles() {
	
	
	for f in *.[jJ][pP][gG]
		do
			COUNT=`expr $COUNT + 1`
		done
	
}

setcount() {
	COUNT2=`echo "scale=2; 100/$COUNT" |bc -l`
	COUNT3=`echo "scale=2; 100/$COUNT" |bc -l`
	COUNT4=`echo "$COUNT2" |cut -f1 -d"."`
}



Xresize() {
	for files in *.[jJ][pP][gG]
	do
		convert -resize "$SIZE"x"$SIZE" "$files" "$RESIZEDIR"/"r_$files" 2>/dev/null
		if [ $COUNT4 -gt 100 ]; then
			COUNT4=100
		fi
		echo $COUNT4
		echo XXX
		echo "Resizing... ($COUNT2 percent)"
		echo XXX
		COUNT2=`echo "scale=2; $COUNT2 + $COUNT3" | bc -l`
		COUNT4=`echo "$COUNT2" |cut -f1 -d"."`
	done| Xdialog --title "JPG Resizer" --gauge "Resizing..." 10 70 0
	
}

prog_term() {
	Xdialog --title "JPG Resizer" --msgbox "Program terminated" 10 30
	rm -f $tempfile
	exit 1
}


helpme() {
cat << EOF >$tempfile
	Script for JPEG resizing with wizard (from Xdialog). 
	Copyright (c) 2005 by Sahachart Anukulkitch. Distributed under GPL.
	
	The script will resize all JPEG files with specified size 
	(in percent) using wizard. Hope this will make picture
	resizing job easier ;). 
	
	Actually, if you want, just replace "jpg" in the script to other 
	image extensions such as png, bmp, xpm and so on. This script will 
	work for you to resize other image file types.
	
	Usage:
		Xjpgresize [option]
			-h display this help dialog and exit
			-v display version dialog and exit
	
		Without option, the script will start the wizard to resize 
		JPEG files. Choose the directory containg files you want, 
		enter the size and directory name that will be used to 
		keep the resized files. 
EOF
Xdialog --title "JPG Resizer Help"  --textbox $tempfile 30 100
rm -f $tempfile
exit 0
}

version() {
Xdialog --title "JPG Resizer" --msgbox "The JPEG resizing script version 0.3.1x, with Xdialog" 10 70
exit 0
}

wizard_start() {
	Xdialog --title "JPG Resizer" --left --wizard \
	--yesno "Welcome to JPG Resizer Wizard version 0.3.1x. \\nClick Next to proceed \\nor Cancle to terminate program. \\n \\n \\n \\nCopyright (c) 2005 by Sahachart Anukulkitch. \\n \\nYou can modify or redistributed this under GPL" 30 70
	case $? in
		0) choose_dir_wiz
		;;
		1) prog_term
		;;
		3) prog_term
	esac

}
	
choose_dir_wiz() {
	Xdialog --title "JPG Resizer - Please choose a directory" --wizard\
	--help "Please choose the directory contaning files \\n you wish to resize"\
	--dselect ~ 30 70 2>$tempfile

	case $? in
		0)  
		D_SELECTED=`cat $tempfile`
		cd "$D_SELECTED"		
		#test if there are JPEG files in the directory

		if [ -z `ls |grep -i "\.jpg"` ] 2>/dev/null
			then
			Xdialog --title "JPG Resizer" \
			--msgbox "There're no JPEG files in this directory." 10 70
			rm -rf $tempfile
			exit 1
		fi
		get_dir
		;;
		1) prog_term
		;;
		3) wizard_start
		;;
	esac
}

get_dir() {
	Xdialog --title "JPG Resizer" --left --wizard \
	--inputbox "Please enter directory name you want to keep files" 30 70 \
	"resized"  2>$tempfile

	case $? in
		0) 
		RESIZEDIR="`cat $tempfile`"
		get_size
		;;
		1) prog_term
		;;
		3) choose_dir_wiz
		;;
	esac
}

get_size() {
	Xdialog --title "JPG Resizer" --wizard \
	--rangebox "Use slide bar to choose size (%)" 30 70 1 99 50 2>$tempfile

	case $? in
		0)
		SIZE="`cat $tempfile`%"
		;;
		1) prog_term
		;;
		3) get_dir
		;;
	esac
}

#==============================================================================

#main program
#test the arguments using case

case $1 in
	-h)
		helpme
		;;
	-v)
		version
		;;
	*)
		;;
esac

#start the wizard

wizard_start



#check if directory is existed or create directory
if [ -d $RESIZEDIR ]; then
	Xdialog --title "JPG Resizer" --msgbox "The `pwd`/$RESIZEDIR exists." 7 70
else
	
	Xdialog --title "JPG Resizer" --yesno "Create `pwd`/$RESIZEDIR?" 10 70
	case $? in
		0) mkdir -p $RESIZEDIR
		;;
		1) prog_term
		;;
	esac
fi
#get number of files
numfiles
#set the COUNT- variables
setcount
#resize and display progress bar
Xresize

#get exit status from progress bar
case $? in 
	0)
	Xdialog --title "JPG Resizer" --msgbox "Resizing completed! \\n Click OK to finish the Wizard" 30 70 
	;;

	255)
	Xdialog --title "JPG Resizer" --msgbox "Program aborted!" 7 30
	;;
esac

rm -f $tempfile
#End

ปล. จริงๆ ใช้ gwenview หรือ digikam ทำเอาก็ได้ อาจจะดีกว่าด้วย เพราะมีปลั๊กอิน batch resize แถม Xdialog ก็หยุดพัฒนาแล้วด้วย เลยมีแต่หน้าตาน่าเกลียดๆ แบบ gtk+ (1.x) เท่านั้น แต่อันนี้เขียนเอาไว้ลองวิชาครับ อยากลอง port ไปใช้ kdialog ของ KDE ดูเหมือนกัน แต่ความยืดหยุ่นสู้ Xdialog ไม่ได้