Cristina Heredia

Outlier y graduada en Ing. Informática en la ugr. Computer science.

More Cristina Heredia's posts

Spot a typo?: Help me fix it by contacting me.

Sure you are that kind of person that spend hours in front of a computer with one or more terminals open. And sure, you are very used to the shell black background with white letters, or whatever shell style you put long time ago… Because, lets be honest, changing it everyday is not the most fun job. But… What if it changes itself automatically? What if you could just have your favorite pictures as shell backsground’s images, with a text that suits the colors in each of that images and you just have to no nothing?

Here I want to tell you how I thought to do it with a bash script, and thus escape from the shell style routine.

Before we start…

Check you gnome-shell version

That script is valid only for gnome versions < 3.8. I Have tested it in Linux Mint Debian Edition and in Ubuntu 14.04 (in this last I had to install gnome-shell).

To install gnome-shell (just in case you need to):

    cris@cris ~ $ sudo apt-get install gnome-shell

to check the gnome version:

    cris@cris ~ $ gnome-shell --version

Install ImageMagick and gawk

We are goint to use some ImageMagick functions to convert the images, and gawk for filtering expressions. To install them:

    cris@cris ~ $ sudo apt-get install gawk
    cris@cris ~ $ sudo apt-get install imagemagick

Script explanation

What we want this script to do is to modify directly the shell configuration values that are set in the file %gconf.xml which is placed at home/user/.gconf/apps/gnome-terminal/profiles/Default/ for gnome versions < 3.8.

Variables definition

Initially, we are declaring the variables with the path of the commands we are going to use frequently. It is not mandatory, but it is recommended. The ROUTE variable contains the path for the folder where the images that we want to use as background images are placed.



Taking Images

We take randomly an image of myPath for the shell background:

    FILE=$(shuf -n 1 -e $ROUTE)

We clear the path name and take only the image’s name:

    FILECONV=$(basename "$FILE")

Lets resize the image (just if needed, for example if the images we want to use are for desktop background). To not modify the original image neither keeping so many unnecessary copies, we save it in /tmp.

    convert "$FILE" -resize %50 "/tmp/$FILECONV"

As my images are desktop background size, I resize them to the half of their size to fit better the shell.

Optional: we take another image from the folder to set it as desktop background image:

    FILED=$(shuf -n 1 -e $ROUTE)

Set the terminal’s background image

We modify some configurations that are by default before applying changes, to have an effect:

    $GCONFT --set /apps/gnome-terminal/profiles/Default/background_type --type string "image" #solido por defecto

    $GCONFT --set /apps/gnome-terminal/profiles/Default/use_custom_command --type bool "false"

    $GCONFT --set /apps/gnome-terminal/profiles/Default/use_theme_colors --type bool "false"

    $GCONFT --set /apps/gnome-terminal/profiles/Default/use_custom_default_size --type bool "true"

Now, we can just take the resized image and set it as terminal’s background image:

    $GCONFT --set /apps/gnome-terminal/profiles/Default/background_image --type string "/tmp/$FILECONV"

Last, we set a dark background color for shell and a high opacity level, to make the text looks better:

    $GCONFT --set /apps/gnome-terminal/profiles/Default/background_color --type string "#181824243131"

    $GCONFT --set /apps/gnome-terminal/profiles/Default/background_darkness --type float "0.78"

Set the text color to suit with the image

To do that, we first get the color hibstogram from the image, and then we take a color tone of them. With convert we can specify the number of colors to take and the deeper we want to go in the image to get them. Then, we sort then according to their numeric order and filter just the hexadecimal code of the colors with gawk. We save it in a text file called paleta.txt which will be created at /tmp.

    $CNVRT "/tmp/$FILECONV" -colors 25 -depth 6 -format '%c' histogram:info:- \
    | $SORT --general-numeric-sort \
    | $GAWK 'match ($0, /^ *[0-9]+: \([^)]+\) (#[0-9A-F]+) .+$/, a) { print a[1] }' > "/tmp/paleta.txt"

To finish, we open the temporary file paleta.txt and read the first 6 lines from it, that is, we read the first 6 colors:

    # open file
    exec 3< /tmp/paleta.txt
    #read 6 lines
    read color1 <&3
    read color2 <&3
    read color3 <&3
    read color4 <&3
    read color5 <&3
    read color6 <&3
    exec 3<&-

and we set the last readed color as the shell’s text color:

    $GCONFT --set /apps/gnome-terminal/profiles/Default/foreground_color --type string "$color6"

Why taking the 6º color? well thats because as colors are ordered from dark to light, the lighther ones, that are the ones that give better results, are in the center possition of the hibstogram. However, you can modify it depending on your images. The script is not perfect! the image folder I use has 700 images and there is sometimes someone that fails suiting with text color, especially the very dark images where no light colors can be found. If you have any idea of improvement, comment it or let me know!

Optional: if you also want to change the desktop background image:

    gsettings set org.gnome.desktop.background picture-uri "file:///$FILED"

Enjoy and show off your terminals

Plan it execution

To avoid executing the script by hand, you can automate it execution using crontab, for example, if you want it to execute each time you boot your pc:

    cris@cris ~ $ crontab -e # open crontab
    @reboot /path_to_script/ # add task

Some examples

Link to code

You can check the script at github


Maybe this posts are also worth reading