Today we’re going to take a photo, overlay some text and graphics on it and then tweet it. In this series, we’ve been building a Raspberry Pi Twitter app and we’re adding more to it. This is a great way to develop software. Add things one step at a time and don’t move on to the next part until it works well, and you understand it.
Why Would You Want To Do This?
Let me backtrack and explain why I wanted to do this in the first place. I have a weather station running on a Raspberry Pi. It logs the following data to Xively…
- Inside temperature
- Outside temperature
- Inside light level
- Outside light level
- Barometric pressure
When away from the house, I like to monitor what’s happening. I have security cameras for this, but last summer I used a Pi camera as well.
So, I thought it would be cool if I could grab the weather station data from Xively and overlay that on a photo of the garden, along with time and date, and then tweet the photo. It sounds hard, but it didn’t take long to find out how to do it.
And then I thought “What about overlaying a logo as well?” That didn’t take too long to work out either.
What I’m Not Covering
I’m not going to cover the specifics of how I get the data from Xively because…
- I’m using the obsolete COSM pachube interface (it still works, but it’s not the way forward).
- Whatever text you want to overlay, may come from a totally different place, so it wouldn’t be helpful for you
But I am going to cover the mechanics of doing the text and graphics overlay. So how do we do the overlays?
I had no idea how to overlay text on a photo, but I headed over to the Raspberry Pi forums and did a search. It didn’t take long to find a helpful thread.
It can all be done with an excellent package called ImageMagick. So let’s install it…
sudo apt-get update (update package list)
sudo apt-get install imagemagick (install program)
From the command line, this is how it works…
convert your_photo.jpg -pointsize 36 -fill white -annotate +40+728 'your overlay text' your_output_photo.jpg
There are a couple of traps though because, from within a program, it’s better to specify the full path to files and programs. So it becomes…
/usr/bin/convert /path/to/your_photo.jpg -pointsize 36 -fill white -annotate +40+728 'your overlay text' /path/to/your_output_photo.jpg
So What Does This Do?
It takes the photo your_photo.jpg and overlays the text your overlay text 40 pixels in from the left-hand edge and 728 pixels from the top edge. The text will be 36 points high and white. The resulting file is saved as your_output_photo.jpg, but you can use the same filename and path as the input file to overwrite the original.
This is incredibly powerful and – once you’ve got your head round it – not very hard. So the program does this step for each piece of data it wants to overlay. There is a way to change the font, but I had trouble with it, so stayed with the default font.
But I want logos too. :)
We use the same program as before, but different command arguments and parameters…
/usr/bin/convert /path/to/your_photo.jpg /home/pi/overlay.png -geometry +1+1 -composite path/to/your_modified_photo.jpg
This uses ‘convert’ to take your_photo.jpg and overlay the file overlay.png 1 pixel from the left-hand edge and 1 pixel down from the top edge. It puts the output in the file your_modified_photo.jpg
So, in my program, I ran this command twice. Once for each logo. It’s a good idea to make sure your logos are a suitable size. If they’re not, you can scale them, but if you’re doing the same thing over and over again, it’s more efficient to do that processing once and in advance.
So What About the Code Then?
Here is a slightly modified version of the code I used at the Cambridge Raspberry Jam last weekend to tweet photos of people who visited the HDMIPi stand.
#!/usr/bin/env python2.7 # tweetpic6BLOG.py by Alex Eames https://raspi.tv/?p=6004 # take a photo with the Pi camera, overlay some text # then overlay a small logo and tweet the final image import tweepy from time import sleep from subprocess import call from datetime import datetime import sys if len(sys.argv) >= 2: tweet_text = sys.argv else: tweet_text = "Photo from insert your location here" if len(tweet_text) > 110: print "tweet not sent. Too long. 110 chars Max. Try again." sys.exit() # Twitter Bits. Consumer keys and access tokens, used for OAuth consumer_key = 'copy your consumer key here' consumer_secret = 'copy your consumer secret here' access_token = 'copy your access token here' access_token_secret = 'copy your access token secret here' # OAuth process, using the keys and tokens auth = tweepy.OAuthHandler(consumer_key, consumer_secret) auth.set_access_token(access_token, access_token_secret) # Creation of the actual interface, using authentication api = tweepy.API(auth) def photo_tweet(): i = datetime.now() now = i.strftime('%Y%m%d-%H%M%S') tweettime = i.strftime('%Y/%m/%d %H:%M:%S') photo_name = now + '.jpg' cmd = 'raspistill -t 500 -w 1024 -h 768 -o /home/pi/' + photo_name print 'cmd ' +cmd print "about to take photo" call ([cmd], shell=True) print "photo taken" photo_path = '/home/pi/' + photo_name status = tweet_text + ' #optionalhashtag ' + tweettime # Add text overlay of data on the photo we just took print "about to set overlay_text variable" overlay_text = "/usr/bin/convert "+ photo_path + " -pointsize 36 -fill white -annotate +40+728 '" + tweettime + "' " overlay_text += " -pointsize 36 -fill white -annotate +40+630 'Your Text annotation here ' " + photo_path print "overlaying text" call ([overlay_text], shell=True) print "adding your logo" # you'll need a file called overlay.png in /home/pi overlay_text = '/usr/bin/convert '+ photo_path + ' /home/pi/overlay.png -geometry +1+1 -composite ' + photo_path call ([overlay_text], shell=True) print "added logo 1" print "tweeting photo" api.update_with_media(photo_path, status=status) print "photo tweeted, deleting .jpg" cmd = 'rm ' + photo_path call ([cmd], shell=True) print 'start of program' photo_tweet()
There is one major caveat. The spaces at the ends of lines 49 (“‘ “), 50 (‘ “) and 56 (composite ‘) are essential or the imagemagick convert command will fail.
A minor caveat is that I use the same path/filename for the input and output of all overlays, which means that the original photo is overwritten at each step.
Here’s an explanation of what the code does…
1 shebang line enables this script to be executed directly (if permissions correct)
2-4 and comments
5-9 import required libraries
11-15 use command line input as tweet text, or default set in 15
17-19 ensure tweet text is not too long
21-32 set up twitter interface
34-63 main function defined
35-38 deal with time stamping and photo file name
39-43 take the photo
44 set full photo file path
45 assemble the full tweet text
48-53 build and execute the ‘convert’ text overlay command
55-58 build and execute the ‘convert’ graphic overlay command
60-61 tweet the overlaid photo
62-64 delete the photo (comment out 64 if you want to keep it)
68 call the main function photo_tweet()
What Does the Output Look Like?
And here’s an embedded tweet from last weekend’s Cambridge Jam, where I used a very similar script to tweet photos from the event. This is myself and Ben Nuttall (although the weather data was still from my home-based weather station)…
— RasP.iO (@RasPiO1) February 8, 2014
At the Cambridge Jam, I realised it would be nice to be able to view the photo afterwards on the HDMIPi screen that was attached to the Pi.
So I’ve implemented that for next week’s Oxford Jam (watch for the hashtag #OxJam on 18th Feb in the evening).
I think our work here with twitter and Python tweepy may be nearly done. I may discover more we can add, but for the time being I may well take a break. We’ll see how it goes. I hope you’ve enjoyed the series. Let us know how you get on and if you make a twitter app of your own.
I’ve created an index page of all the twitter app on the Raspberry Pi series here https://raspi.tv/raspitweets
And you can download the full set of Python scripts from my Github repo here
or, from Pi command line, use…
git clone https://github.com/raspitv/raspitweets