ubuntu / Mint下 实现动态桌面壁纸切换 XML配置文件生成实用perl脚本

实现原理是使用一个xml文件来记录可供切换选择的壁纸。下面展示的是10.04中自带的一个样例。

首先说明一下,ubuntu默认的壁纸存放在/usr/share/backgrounds/目录下的,在该目录中还有一个cosmos(意思是“宇宙”)目录,cosmos里面的xml文件就是实现动态桌面壁纸切换功能的了。

本脚本就是对给定图片文件夹快速生成相应xml配置文件。

现在关键是生成相应的xml配置文件了,里面的类容比较繁杂,手动更新太麻烦了,所以想到以脚本实现。

1.perl写成的源代码如下:

#!/usr/bin/perl 
#==============================================================================#
#-------------------------------help-info-start--------------------------------#
=head1 Name

	getBackgroundXML.pl --> generate the background.xml file to change Ubuntu background picture dynamiclly

=head1 Usage

	perl  getBackgroundXML.pl  [<options>] [-d PicDir='.'] [-t TimeToLast=1795.0] [-i Interval=5.0] [-o Background.xml=STDOUT]

	-help       print this help to screen
	-a          flag ,if set ,write all pictures to one xml file
	-d          directory contains the jpgs, defalt : '.'
	-t          time to change background picture, unit : seconds, default : 1795.0
	-i          interval time spend to change the two pictures, default : 5.0
	-o          write result to a file , default : STDOUT

=head1 Example

	perl  getBackgroundXML.pl  -d Windows7 -t 25 -i 5 -o Windows7.xml
	perl  getBackgroundXML.pl  --

=head1 Version

	Verion	:	2.0
	Created	:	08/18/2010 03:34:52 PM 
	Updated	:	08/18/2010 09:51:11 PM
	LastMod	:	---


=head1 Contact

	Author	:	QuNengrong (Qunero)
	E-mail	:	[email protected],[email protected]
	Company	:	BGI

=cut
#-------------------------------help-info-end--------------------------------#
#============================================================================#
use strict;
use warnings;
use Getopt::Long;

my ($Need_help, $Out_file, $PicDir, $TimeToLast, $Interval, $AllInOne );
GetOptions(
	"help"		=> \$Need_help,
	"a"		=> \$AllInOne,
	"d=s"		=> \$PicDir,
	"t=i"		=> \$TimeToLast,
	"i=i"		=> \$Interval,
	"o=s"		=> \$Out_file,
);

die `pod2text $0` if ($Need_help);

#============================================================================#
#                              Global Variable                               #
#============================================================================#
my $Input_file  = $ARGV[0]  if (exists $ARGV[0]); 
$PicDir ||= '.';
$TimeToLast ||= 1795.0;
$Interval ||= 5.0;
$PicDir =~ s/\/$//;
$PicDir =~ s/ /\\ /g;                           # replace SPACE to \SPACE ;
#print STDERR "$0 -d $PicDir -t $TimeToLast \n";
#============================================================================#
#                               Main process                                 #
#============================================================================#

if(defined $Input_file)
{ open(STDIN, '<', $Input_file) or die $!; }
if(defined $Out_file)
{ open(STDOUT, '>', $Out_file) or die $!; }

print STDERR "---Program\t$0\tstarts--> ".localtime()."\n";
	
# step 01: getBackgroundXML
&getBackgroundXML();

print STDERR "---Program\t$0\t  ends--> ".localtime()."\n";

#============================================================================#
#                               Subroutines                                  #
#============================================================================#

sub getBackgroundXML(){
#	my @picFiles = `ls $PicDir |grep .jpg`;     # it's better than glob , in case $PicDir is ~/subDir
	my @picFiles ;
	if( $AllInOne ){
#		@picFiles = glob ( "$PicDir/*/*.jpg" );
		@picFiles = `find $PicDir/ -name "*\.jpg"`;
	}
	else {
		@picFiles = glob ( "$PicDir/*.jpg" );
	}

#	print STDERR "test files:\n\t", join( "\t", @picFiles );
	chomp( @picFiles );


	if( $PicDir =~ /^\// ){
		for( @picFiles ){
#			$_ = "$PicDir/$_";                  # already full path;
			$_ =~ s/ /\\ /g;
		}

	} 
	else {                # path start with ./ OR ../ OR subDir/
		my $curDir = `pwd`;
		chomp( $curDir );
		for( @picFiles ){
			$_ = "$curDir/$_";
			$_ =~ s/ /\\ /g;
			$_ =~ s/\/\.\//\//g;                # change /./ to /
			$_ =~ s/\/[^\/]+\/\.\.\//\//;       # change path/dir/../anotherDir/ to path/anotherDir/
		}
	}
	
	#	print STDERR join( "\n", @picFiles );

	my $oldjpg = $picFiles[-1];
	print STDOUT 
"<background>
	<starttime>
		<year>2010</year>
		<month>08</month>
		<day>18</day>
		<hour>00</hour>
		<minute>00</minute>
		<second>00</second>
	</starttime>
	<!-- This animation will start now. -->\n";

	for ( @picFiles ){
		printf STDOUT 
"	<static>
		<duration>%.1f</duration>
		<file>$oldjpg</file>
	</static>
	<transition>
    	<duration>%.1f</duration>
		<from>$oldjpg</from>
		<to>$_</to>
	</transition>\n", $TimeToLast, $Interval ;
	$oldjpg = $_;
	}
	print "</background>\n";

}

脚本使用简单说明:

1.运行时最好使用完整路径,指明图片所在的目录,例如:

getBackgroundXML.pl -d pathtowallpaper/Windows7/ -o Windows7/background.xml

2.默认图片文件路径为当前目录,文件类型为jpg,默认输出结果到终端,保存需加上-ofilename;

3.设置好后的应用方法:右键桌面->更改桌面背景->添加,在弹出对话框的右下方那里选择“全部文件”(默认是“图像”),然后找到你定义好的动态桌面壁纸的xml文件,双击添加就可以了。

4.感兴趣的实验:

1)加入可选参数-t指定切换时间,默认半小时左右。

2)优化代码,让其可移植性更好~~

5.附件可以去ubuntu论坛下载,以及几张漂亮的window7图片,background.xml需要根据你的路径修改后在使用~~,祝大家玩得开心、用得顺手!

附件和源码下载,请见ubuntu论坛:http://forum.ubuntu.org.cn/viewtopic.php?f=21&t=289599