• 在GNU/Linux下设置与定时更换桌面壁纸


    1 简介

    在电脑桌面设置一组可以定时更换的壁纸已经不是什么新奇的功能了。比如,Windows 7、KDE桌面环境都可以实现这样的效果。可是,自己目前使用的Debian系统并未安装KDE、GNOME这样的桌面环境,只是简单的X视窗系统与Sawfish窗口管理。因此,要想实现加载壁纸并定时更换的功能就需要另想办法了。经过一番思考与编程,我现在可以用如下一系列脚本程序来完成这个任务:

    1. get_img_size.sh :调用 identify 命令显示图片信息并使用 gawk 命令从中提取出图片的尺寸。
    2. set_wallpaper.sh :调用 xloadimage 程序,加载单张图片作为壁纸。其中,该脚本会调用 get_img_size.sh 以获取该图片的尺寸,并根据指定的屏幕大小与其所在位置,对该图片进行适当的缩放与平移,使其显示于屏幕中间,且保持原比例充满屏幕。
    3. set_multi_wallpapers.sh :读入包含壁纸图片列表的配置文件,以指定的时间间隔来调用 set_wallpaper.sh ,从而逐个将这些图片加载为壁纸。
    4. gen_multi_wallpapers.sh :根据指定的匹配模式,使用 find 命令列出匹配到的图片文件,并生成能被 set_multi_wallpapers.sh 使用的配置文件。

    下面对上述脚本进行具体说明。

    2 加载单张图片作为壁纸: set_wallpaper.sh

    将图片作为壁纸显示是通过 xloadimage 命令来实现的。通常,可以按如下的方式使用它:

    xloadimage -fullscreen -onroot -border black -zoom 100 -rotate 90 -at 0,0 image_file
    

    其中, -fullscreen-onroot 的使用就可以将图片作为壁纸显示而不是被放到一个窗口里。其余的命令行选项的含义都是不言自明的。 set_wallpaper.sh 脚本程序并不是简单地调用 xloadimage ,其还会根据图片的大小与屏幕尺寸计算出 -zoom 选项的值,从而自动缩放图片,使其恰好完整地填满屏幕。此外,若电脑连接有多个显示器,可以通过设置 set_wallpaper.sh-x-y 选项来指定待加载壁纸屏幕左上角的坐标,以及设置 -W-H 选项来指定该屏幕的宽和高。最终,图片就会只在该屏幕上显示了。

    set_wallpaper.sh 的源码如下:

    #!/bin/bash
    
    script_name="set_wallpaper.sh"
    script_usage=$(cat <<EOF
    $script_name [OPTION] image_file
    EOF
    )
    script_function=$(cat <<EOF
    This script is used to load an image onto root screen as wallpaper.
    EOF
    )
    script_doc=$(cat <<EOF
    -h     Display this help.
    -r     Set the rotation angle of the image.
    -W     Screen width.
    -H     Screen height.
    -x     X position of the image to be loaded onto root screen.
    -y     Y position of the image to be loaded onto root screen.
    EOF
    )
    script_examples=$(cat <<EOF
    $script_name -r 0 -W 1920 -H 1080 -x 1280 -y 0 $picture/wallpapers/sunflower.jpg
    EOF
    )
    state_prefix="==="
    warning_prefix="***"
    error_prefix="!!!"
    
    function display_help() {
        if [ -n "$script_usage" ]; then
            echo -e "Usage: $script_usage"
        fi
    
        if [ -n "$script_function" ]; then
            echo -e "$script_function"
        fi
    
        if [ -n "$script_doc" ] ; then
            echo -e "
    $script_doc"
        fi
    
        if [ -n "$script_examples" ]; then
            echo -e "
    Examples"
            echo -e "$script_examples"
        fi
    }
    
    # Default parameters
    declare -i rot_angle=0 screen_width=1920 screen_height=1080 screen_x=0 screen_y=0 zoom_factor=100 x_res=0 y_res=0 x_res_scaled=0 y_res_scaled=0 at_x=0 at_y=0
    
    while getopts ":r:W:H:x:y:h" opt; do
        case $opt in
            r  )  rot_angle=$OPTARG
                  if [ $(((($rot_angle % 90) != 0) || (($rot_angle < 90) && ($rot_angle != 0)))) = 1 ]; then
                      echo "The rotation angle of the image should be 0 or multiple of 90 degrees!"
                      exit 1
                  fi ;;
            W  )  screen_width=$OPTARG ;;
            H  )  screen_height=$OPTARG ;;
            x  )  screen_x=$OPTARG ;;
            y  )  screen_y=$OPTARG ;;
            h  )  display_help
                exit 0 ;;
            ? )  display_help
                exit 1 ;;
        esac
    done
    
    shift $(($OPTIND - 1))
    
    if [ -n "$1" ]; then
        echo "Loading image $1"
        resolution=`get_img_size.sh "$1"`
        x_res=`echo $resolution | gawk -F x '{print $1}'`
        y_res=`echo $resolution | gawk -F x '{print $2}'`
    
        # If the rotation angle is odd times of 90 degrees swap x and y
        # resolutions of the image
        if [ $((($rot_angle / 90 % 2) == 1)) = 1 ]; then
            tmp_res=$x_res
            x_res=$y_res
            y_res=$tmp_res
        fi
        echo "Image resolution is ${x_res}x${y_res}"
    
        # Calculate the scaling factor of the image to fit to the screen
        if [ $((($x_res * 100 / $y_res) < ($screen_width * 100 / $screen_height))) = 1 ]; then
            # Scale the height of the image
            if [ $(($y_res > $screen_height)) = 1 ]; then
                zoom_factor=$(($screen_height * 100 / $y_res))
            else
                zoom_factor=$(($y_res * 100 / $screen_height))
            fi
            echo "Scaling in the y direction!"
            at_y=$screen_y
            at_x=$((($screen_width - $x_res * $zoom_factor / 100) / 2 + $screen_x))
        else
            # Scale the width of the image
            if [ $(($x_res > $screen_width)) = 1 ]; then
                zoom_factor=$(($screen_width * 100 / $x_res))
            else
                zoom_factor=$(($x_res * 100 / $screen_width))
            fi
            echo "Scaling in the x direction!"
            at_x=$screen_x
            at_y=$((($screen_height - $y_res * $zoom_factor / 100) / 2 + $screen_y))
        fi
        echo "Zoom factor is $zoom_factor"
        echo "Image location is $at_x,$at_y"
    
        rot_opt=""
        if [ $(($rot_angle != 0)) = 1 ]; then
            rot_opt="-rotate $rot_angle"
        fi
        xloadimage -fullscreen -onroot -border black -zoom $zoom_factor $rot_opt -at $at_x,$at_y "$1"
    else
        echo "Please provide an image!"
        exit 1
    fi
    

    其中,用于获取图片大小的脚本 get_img_size.sh 内容如下:

    #!/bin/bash
    
    if [ -n "$1" ]; then
        identify "$1" | gawk '{if(match($0, /([[:digit:]]+)x([[:digit:]]+)/, res) != 0) print res[0];}'
    else
        echo "Please provide an image!"
        exit 1
    fi
    

    3 定时加载多张壁纸: set_multi_wallpapers.sh

    通过 -s 选项,可以指定配置文件,其由该脚本读入后以默认的时间间隔60秒或由 -t 选项指定的时间间隔来逐个显示列表中的图片。配置文件的格式如下:

    # Configuration file storing list of images to be loaded onto root screen as wallpapers.
    
    # Description of data columns (columns are separated by TAB):
    # Column 1: Absolute path to image
    # Column 2: Rotation angle applied to the image
    # Column 3: X position of the image to be loaded onto the root screen
    # Column 4: Y position of the image to be loaded onto the root screen
    
    /home/orlando/Pictures/wallpapers/Windows 10 wallpapers/02 - wqQXJGJ.jpg        0       1280    0
    /home/orlando/Pictures/wallpapers/Windows 10 wallpapers/03 - jVKcv41.jpg        0       1280    0
    /home/orlando/Pictures/wallpapers/Windows 10 wallpapers/04 - wPpANVz.jpg        0       1280    0
    /home/orlando/Pictures/wallpapers/Windows 10 wallpapers/05 - yGQyrcX.jpg        0       1280    0
    /home/orlando/Pictures/wallpapers/Windows 10 wallpapers/07 - XaanvJe.jpg        0       1280    0
    /home/orlando/Pictures/wallpapers/Windows 10 wallpapers/08 - zl3dIFY.jpg        0       1280    0
    /home/orlando/Pictures/wallpapers/Windows 10 wallpapers/09 - VD7t2al.jpg        0       1280    0
    /home/orlando/Pictures/wallpapers/Windows 10 wallpapers/10 - GjUEn90.jpg        0       1280    0
    /home/orlando/Pictures/wallpapers/Windows 10 wallpapers/11 - qX58uOK.jpg        0       1280    0
    /home/orlando/Pictures/wallpapers/Windows 10 wallpapers/20 - 1QqFwJU.jpg        0       1280    0
    /home/orlando/Pictures/wallpapers/Windows 10 wallpapers/Diver.jpg       0       1280    0
    

    set_multi_wallpapers.sh 脚本内容如下:

    #!/bin/bash
    
    script_name="set_multi_wallpapers.sh"
    script_usage=$(cat <<EOF
    $script_name [OPTION]
    EOF
    )
    script_function=$(cat <<EOF
    This script is used to display a set of images onto root screen as wallpapers.
    EOF
    )
    script_doc=$(cat <<EOF
    -h     Display this help.
    -s     Source file storing list of image paths and parameters. If this is not given, ~/.multi_wallpapers will be used.
    -t     Time interval between each image. If this is not given, default interval is 60 seconds.
    -W     Screen width.
    -H     Screen height.
    EOF
    )
    script_examples=$(cat <<EOF
    $script_name            # Load images in ~/.multi_wallpapers as wallpapers with an interval of 60 seconds.
    $script_name -s /path/to/image_list_file -t 5 # Specify image list file and time interval.
    EOF
    )
    state_prefix="==="
    warning_prefix="***"
    error_prefix="!!!"
    
    function display_help() {
        if [ -n "$script_usage" ]; then
            echo -e "Usage: $script_usage"
        fi
    
        if [ -n "$script_function" ]; then
            echo -e "$script_function"
        fi
    
        if [ -n "$script_doc" ] ; then
            echo -e "
    $script_doc"
        fi
    
        if [ -n "$script_examples" ]; then
            echo -e "
    Examples"
            echo -e "$script_examples"
        fi
    }
    
    # Default parameters
    image_source_file="/home/orlando/.multi_wallpapers"
    time_interval=60
    screen_width=1920
    screen_height=1080
    
    # Process command options
    while getopts ":ht:s:W:H:" opt; do
        case $opt in
            h  )  display_help
                exit 0 ;;
            s  )  image_source_file=$OPTARG ;;
            t  )  time_interval=$OPTARG ;;
            W  )  screen_width=$OPTARG ;;
            H  )  screen_height=$OPTARG ;;
            ? )  display_help
                exit 1 ;;
        esac
    done
    shift $(($OPTIND - 1))
    
    # Start execute the command
    IFS=$'
    '
    if [ -e "$image_source_file" ]; then
        while [ 1 ]; do
            for image_info in `cat "$image_source_file" | grep "^[^#].*"`; do
                image_name=`echo "$image_info" | cut -f 1`
                rot_angle=`echo "$image_info" | cut -f 2`
                x_pos=`echo "$image_info" | cut -f 3`
                y_pos=`echo "$image_info" | cut -f 4`
    
                if [ -e "$image_name" ]; then
                    set_wallpaper.sh -r "$rot_angle" -W "$screen_width" -H "$screen_height" -x "$x_pos" -y "$y_pos" "$image_name"
                else
                    echo -e "$error_prefix Image $image_name does not exist!"
                fi
    
                sleep $time_interval
            done
        done
    else
        echo -e "$error_prefix Configuration file $image_source_file does not exist!"
    fi
    

    4 生成多张壁纸配置文件: gen_multi_wallpapers.sh

    该脚本可以在指定的目录下(第一个参数),根据指定的正则表达式(第二个参数)来搜索出匹配的图片文件,然后将其按上述配置文件的格式显示出来。脚本内容如下:

    #!/bin/bash
    
    script_name="gen_multi_wallpapers.sh"
    script_usage=$(cat <<EOF
    $script_name [OPTION] path_name regex_pattern
    EOF
    )
    script_function=$(cat <<EOF
    Generate configuration for a list of wallpaper images.
    EOF
    )
    script_doc=$(cat <<EOF
    -h     Display this help.
    -c     Display the comment for configuration file.
    -x     X position of the image to be loaded onto root screen.
    -y     Y position of the image to be loaded onto root screen.
    EOF
    )
    script_examples=$(cat <<EOF
    $script_name -x 1280 ./ "\(.*jpg\)\|\(.*JPG\)"
    EOF
    )
    state_prefix="==="
    warning_prefix="***"
    error_prefix="!!!"
    
    function display_help() {
        if [ -n "$script_usage" ]; then
            echo -e "Usage: $script_usage"
        fi
    
        if [ -n "$script_function" ]; then
            echo -e "$script_function"
        fi
    
        if [ -n "$script_doc" ] ; then
            echo -e "
    $script_doc"
        fi
    
        if [ -n "$script_examples" ]; then
            echo -e "
    Examples"
            echo -e "$script_examples"
        fi
    }
    
    # Default parameters
    x_pos=0
    y_pos=0
    comment_string=$(cat <<EOF
    # Configuration file storing list of images to be loaded onto root screen as wallpapers.
    
    # Description of data columns (columns are separated by TAB):
    # Column 1: Absolute path to image
    # Column 2: Rotation angle applied to the image
    # Column 3: X position of the image to be loaded onto the root screen
    # Column 4: Y position of the image to be loaded onto the root screen
    EOF
    )
    is_display_comment=0
    
    # Process command options
    while getopts ":chx:y:" opt; do
        case $opt in
            x  )  x_pos=$OPTARG ;;
            y  )  y_pos=$OPTARG ;;
            c  )  is_display_comment=1 ;;
            h  )  display_help
                exit 0 ;;
            ? )  display_help
                exit 1 ;;
        esac
    done
    shift $(($OPTIND - 1))
    
    # Start execute the command
    if [ -n "$1" ] && [ -n "$2" ]; then
        if [ "$is_display_comment" = 1 ]; then
            echo -e "$comment_string
    "
        fi
    
        gawk_cmd=`echo "gawk '{print \$0"\t0\t$x_pos\t$y_pos"}'"`
        find "$1" -regex "$2" -print0 | xargs -n 1 -0 fullpath.sh | eval "$gawk_cmd"
    else
        echo "$error_prefix Please specify search path name and file name pattern!"
    fi
    

    可以看出,该脚本又用到了 fullpath.sh ,用于显示图片文件的绝对路径。 fullpath.sh 的内容如下:

    #!/bin/bash
    
    echo $(cd $(dirname "$1") && pwd -P)/$(basename "$1")
    

    5 脚本的使用

    至此,一切都准备就续,可以按下面的步骤来实战了:

    首先,切换到包含自己喜欢图片的文件夹,执行下面的命令生成配置文件:

    gen_multi_wallpapers.sh -c -x 1280 ./ "\(.*jpg\)\|\(.*JPG\)" > ./.multi_wallpapers
    

    接下来,将下面的命令加入到 ~/.xinitrc 中:

    set_multi_wallpapers.sh -s ./.multi_wallpapers -t 300 &
    

    最后,重启X server即可生效。截了一个视频在这里(不好意思,用的是微软最新发布的Windows 10壁纸)。

  • 相关阅读:
    angularjs表格方式显示数据
    AngularJS $http
    指令
    B2C电商平台开发心得(asp.net+bootstrap)
    项目修改有感_主要是以js、Gridview为主
    ASP.NET 导出gridview中的数据到Excel表中,并对指定单元格换行操作
    AtrousConvolution和dilated convolution
    keras中自定义Layer
    Messes in Reading Source Coding of SSD
    SSD
  • 原文地址:https://www.cnblogs.com/quantumman/p/4619980.html
Copyright © 2020-2023  润新知