With the new social networking Google+ people need to upload pictures to it.
There are tools that transfer pictures from Facebook albums to Google, but this is not convenient because the information on pictures are lost (Facebook crops exif data and resizes pictures with a really low resolution while Google supports pictures up to 2048px on longest side). So re-uploading all your pictures again should be preferred.
Google+ offers a user friendly way to do this through a nice web interface but this may be time consuming because the images are sent to the server and then resized by Google. As you can imagine, transferring huge images and resizing them on server consumes a lot of bandwidth.
Fortunately, there are two great open source tools that, with some scripting, can automate the whole process for you.
ImageMagick and GoogleCL are everything we need.
Moreover the script will, optionally, put a watermark on all the uploaded pictures (don't worry, your original pictures will be left untouched on your disk).
The script is not meant to be the "best way" to upload files on Google+ but a fairly complete guide to most of bash commands and features. This is the reason why if you look at the script code, you'll find that I used different approaches in different parts of the script to achieve the same functionality.
Using the Code
First of all, we should prepare the environment and install the tools (if not already installed in your system).
In a terminal window, we have to:
sudo apt-get install imagemagick
sudo apt-get install googlecl
When both packages are installed, we need to allow GoogleCL to access our Picasa/Google+ account:
google picasa list-albums
The program will ask for the Picasa/Google account and will give a link to click:
Please specify user: email@example.com
Please log in and/or grant access via your browser at
then hit enter.
Once authorized on the web return in the terminal and hit enter.
You will see all albums you already uploaded, if any.
Download the .sh script attached to the article into the ~/bin folder and give it executable permissions with:
sudo chmod a+x ~/bin/UploadToPicasa.sh
Warning: The script uses the ~/Pictures/Watermarked
folder (hardcoded in the script) to store the files before uploading them (and leaves there the files that it didn't upload for an error or because you told the script to not upload them).
If your system has localized folder names, you really should
modify the script to match "Pictures
" with the one you have in your system (for example, in my italian ubuntu 11.10 that folder is named "Immagini
If, at the end of the article, you think you are able to apply some of the concepts explained here you could try to modify the script by extracting the localized Pictures folder from ~/.config/user-dirs.dirs
(if it does exist) with
sed -n 's/\(XDG_PICTURES_DIR[:blank:]*=[:blank:]*"\)\(.*\)"/\2/p'
Don't worry, it's really simple.
You could also try to find a different regular expression that does the same.
GREAT! We are ready to go.
Launch the script with:
It will guide you through the whole process.
Let's analyze how the script actually works...
First of all, the script needs to know where are the pictures to upload. By default, it uses the current folder. You can change it or accept it. If you type a wrong path it will be asked again.
Then it asks about watermarking. You can select the position or "none" if you don't want to watermark the pictures. If you choose to apply a watermark, the script asks for the watermark file. If you don't have any, you can build a simple text-only one (before running the script) with a command like this:
convert -size 600x150 xc:grey30 -font /usr/share/fonts/truetype/ubuntu-font-family/
Ubuntu-BI.ttf -pointsize 40 -gravity center -draw "fill grey70 text 0,0
'Photo by Lino Barreca'" stamp_fgnd.png
convert -size 600x150 xc:black -font /usr/share/fonts/truetype/ubuntu-font-family/
Ubuntu-BI.ttf -pointsize 40 -gravity center -draw "fill white text 1,1
'Photo by Lino Barreca' text 0,0 'Photo by Lino Barreca' fill black text -1,-1
'Photo by Lino Barreca'" +matte stamp_mask.png
composite -compose CopyOpacity stamp_mask.png stamp_fgnd.png stamp.png
The last question is about online album name.
By default, the script uses the folder name so if you have
The name proposed will be "Christmas 2011".
If you leave the album name blank the processed pictures will not be uploaded but left on disk.
Now the script has all required information. You can sit and wait.
If you choose to upload the pictures, they will be removed as soon as the upload completes. If you didn't choose to upload them, you will find the photos into the required folder I was referring into my "warning" above.
Points of Interest
Let's analyze, line by line, all the bash features that the script uses...
First line of the script is a comment (all lines starting with
# are treated as comments). Comments can also be used at the line ends or inside a command.
Line 3 contains:
- Variable declaration (
- Environment variable expansion (
$HOME that contains the user home folder, typically /home/username). The
$ sign is very important in bash and has lots of uses.
String declaration with variable concatenation.
In line 4, you will see:
- Conditional evaluation instruction
! reverses the result of the comparison.
- Square brackets
] are used for evaluation. Double brackets
]] (not shown here) are the extended test evaluation operators. No filename expansion or word splitting takes place between
- File/folder test operator
-d. It returns
true if the argument is a directory.
- Command continuation special character
; allows to specify more than one command on a single line.
if syntax in bash requires the
then keyword to be put on another line.
- Command to create a folder
- Useful parameter
mkdir to create the whole folder tree and not only the last folder. Without
mkdir will fail if "Pictures" doesn't exist.
elif. Allows you to check another condition if the above
if condition evaluates to
- Subshell with backtick: the commands inside
` are executed and the results are evaluated.
- Folder contents listing command
ls. One of the most used commands in unix. It lists everything matching the specification given.
- Useful parameter
-A. It is used to tell
ls to ignore
.. folders. The logic behind here is: tell me what files are inside the folders and store the results in a temporary variable (to be evaluated with the
- Checks for variable definition/contents.
if [ somevariable ] evaluates to
somevariable is defined and contains a value.
echo to print things to user it accepts
strings in double quotes, in single quotes and without quotes (behaviour changes accordingly).
echo to escape characters. It is used to put a new line inside the message instead of using two echo commands (each echo, by default puts a new-line at the end)
Line 8: terminate script with a return value. An exit code of 0 usually means success, anything different means error.
if condition termination:
Line 11: another variable assignment, using the
PWD internal variable (it contains the actual working directory). You could also use
~+ it is the same and contains the same value.
while loop. The
while executes everything inside the
do done block while the condition evaluates to
: it is a built-in nop command, evaluates to
true giving us an infinite loop.
do keyword, normally must be put on a new line but used with
; can be put on the same line (as explained above)
read user input from
-e is used to read a line (until enter is pressed)
-i is used to put something as the default input (in this case the actual value of
-p used to print something (the question)
- variable to store read value into (
SourceFolder specified at the end of the line)
Line 14 contains the
break statement used to exit the infinite loop and already explained commands/keywords.
select command (used here to ask the user to make a choiche). this command is usually needed when you want to create a "menu" of possible operations. Choosen option is stored in
- subshell with
$ (another use of the
$ sign). The concept here is similar to the backticks already explained: execute the command inside parentesis and store the result in a variable.
- composite command of the imagemagick package. it returns a list
\n separated of possible parameters to use. The list is stored in a temporary array variable by
$ and used by
select to build a menù.
Line 21: the
break here is used because the select command loops infinitely.
String comparison with the
!= operator (same as C)
String extraction (from
SourceFolder variable) with bash pattern matching. It is a bit long to explain how this actually works (and it's not a "beginner level") but you can find it yourself here and here.
-n option is another way to check if the variable contains a value (same as line 6 last point)
- grep command is another common unix command. It is used to find things.
-q parameter is what we are searching for.
- subshell for the command list-albums of the googlecl package.
- Here string (redirection)
<<< keyword is an advanced bash feature called Here String. Info here. It could be thought as a way to put the contents of the variable into a command.
Line 49 saves the contents of the internal field separator variable
IFS. This is used to determine word boundaries when looking at arrays.
Line 50 replaces the IFS. We need to change this because the
SourceFolder could contain spaces in the path or the files contained could have spaces inside their name.
We need to interpret a path like '/home/user/Pictures/my christmas 2011/Picture 1.JPG' like a SINGLE entry. Without replacing the IFS variable that would be recognized as '/home/user/Pictures/my', 'christmas', '2011/Picture', '1.JPG'
Line 53 contains a
for each loop. It takes a variable after the
in keyword. Each element contained in the variable is assigned to the
each variable and this is used inside the
do done block.
Line 55 contains the
let command. It is used to do aritmetic operations and supports C syntax.
Line 68 contains a pipe
|. Piping is a common task in unix system it is used to pass the output of the command preceding the pipe to the input of the command after the pipe. It is useful to concatenate operations without using temporary files as input/output.
Line 75 contains:
rm command, used to delete a file from disk.
&& operator. It is used to AND things.
Used with conditions it evaluates to
true if all are
Used with commands (like this one), it allow the user to say "if the first command succeeds THEN execute the second command". If the first fails, the second will be skipped (leaving the not-uploaded file on disk)
The first version will also be the last one as it is intended to be a sample on how to use the tools. Take it as a base and modify it as you want (and based on your needs).
If you have any questions/hints or you need help on customizing the script, leave a comment. I'll be glad to help you (when I have some free time).
...and don't forget to rate it, thanks