Duckface lets you apply filters and overlays to images, then post to Twitter and Instagram.

Raspberry Pi Bubo-2T Python Twitter Instagram Pillow Pilgram Tweepy

22 February 2023 by Kevin McAleer | Share this article on



Click here to watch the videos:

Duckface Overview

Duckface is the name I’ve given to this project; its the precursor to the full Bubo robot suite of software I aim to create, ready for Makers Central event in May 2023 at the NEC in Birmingham.


Duckface has the following features:

  • Detect hand gestures using CVZone
  • Take a photo using Picamera2
  • Apply a filter to the photo
  • Add an overlay to the photo
  • Play a cute ‘toot’ sound
  • Tweet the photo to Twitter, along with a randomly generated message
  • Post the photo to Instagram, along with a randomly generated message

Installing the python libraries

You can use pip to install all the libraries mentioned in this article. It’s best practice to use a virtual environment when creating projects in Python, this keeps everything clean and easy to replicate later.

To create a new Virtual Environment simply type:

python3 -m venv venv

To activate the environment use the source command:

source venv/bin/activate

To deactivate the environment use the deactivate command:


Once you’ve activated your Virtual Environment you can add Python libraries using the pip command:

pip install pillow pilgram tweepy instabot

How to include existing system wide packages

To install existing system site wide packages simply use this command line python3 -m venv venv --system-site-packages

Posting to Twitter with Tweepy

Tweepy is a Python library that lets you post to Twitter -

Its pretty simple to setup, though the authentication might look a bit daunting at first.

Security Best Practice

The best practice is to store you credentials in a and then add this filename to your .gitignore file to ensure you don’t accidentally share this with the > world. If someone has access to this they can take over your account.


The file below is an example of what the would look like. You will need to get the Twitter Consumer Key, Consumer Secret, Access Token and Access Token Secret by signing up for a Twitter Developer account, then creating a new Standalone App.

# Dont upload this!

ig_username = "myusername"
ig_password = "mypassword"

# Don't share this file

# Tooty-v1
twitter_consumer_key = '1012k3kjkk3490s0fF3FDFGS5'
twitter_consumer_secret = 'a23BDFGS223456454GFD34HGF6hffgh446y4Ggsewrtgxxllpf'

twitter_access_token = '09123039-ofSSfdr44fSsdf54nbasvJUHF564Hdfgd45Dgpoi7'
twitter_access_token_secret = 'asdfIAS4tfg35365ehf4l34klk4jl4FHG34509G8gdf58'

Next you’ll need to create some code to authenticate to Twitter, using Tweepy, and then you can create a simple post with text and the path to an image file to upload:

import tweepy
from secret import (twitter_access_token, twitter_access_token_secret,
                             twitter_consumer_key, twitter_consumer_secret)
# Authenticate to Twitter
twitter_auth_keys = {
"consumer_key"        : twitter_consumer_key,
"consumer_secret"     : twitter_consumer_secret,
"access_token"        : twitter_access_token,
"access_token_secret" : twitter_access_token_secret

auth = tweepy.OAuthHandler(
api = tweepy.API(auth)

# Path the image file
media = api.media_upload(image_path)

message_text = "This is the body of the tweet, including any #hashtags\n use \n to create new lines"

# Post tweet with image
post_result = api.update_status(status=message_text, media_ids=[media.media_id])

if post_result:
    print("Twitter post sent successfully")
    print("Twitter post reported a failure, though this may not be the case.")

And thats it, you can now create your own TwitterBot!

Posting to Instagram with InstaBot

Posting to Instagram is even easier than twitter, it just needs your username and password for Instagram and then away you go:

from secret import ig_username, ig_password
from instabot import Bot
bot = Bot()
bot.login(username=username, password=password)

if bot.upload_photo(image_path, caption=message_text):
    print("Instagram post sent successfully")

Instagram is less keen on bots posting

You might find that after posting pictures with InstaBot, you might be asked to reauthenticate on your mobile app. This is a security measure to ensure your account hasn’t been hacked.

Image processing in Python with Pillow

Pillow is an image processing library for Python. It has many functions and filters to help you manipulate images using Python.

We will use Pillow to add an image overlay on top of a photo we have already taken. The overlay is just another image, but one that has a transparent background. You can easily create images like this with Apple Keynote, Canva, or Photoshop to name but a few methods.

We also need to resize the overlay image to match that of the background image its being pasted over.

from PIL import Image

""" Add an overlay to the background image. """

background_file = 'overlay.png'
foreground_file = 'snap.jpg'

background =

# resize the foreground image
img =
base_width, base_height = background.size
img_width, img_height = img.size
width_percent = (base_width / float(img_width))
horizontal_size = int((float(img_height) * float(width_percent)))
foreground = img.resize((base_width,horizontal_size), Image.Resampling.LANCZOS)

# paste the foreground image on the background and save the image
background.paste(foreground, (0, 0), foreground)

Apply Instagram like filters using Pilgram

Pilgram is a Python library for applying Instagram-like filters to images.

There are a large number of filters available for you to apply. We’ll pick one for the example below:

import pilgram

image_file = 'snap.jpg'

im =

# apply the filters and save the image

How easy was that? Be sure to check out the github repository to see examples of each filter.

Taking photos with Picamera2

Picamera2 is the latest Raspberry Pi camera library for easy control of the built-in camera module (you can also use it for USB cameras).

We will use Picamera to take pictures and save them to storage.

from picamera2 import Picamera2
picam2 = Picamera2()

PHOTO_FILE = 'snap.jpg'

# Show the camera video feed onscreen

# Take a photo then switch back to the video feed
picam2.switch_mode_and_capture_file("still", PHOTO_FILE)

This code will take a picture and save it to a file named snap.jpg. We can then apply filters to it using Pilgram.

Playing sounds using Pydub

Bubo-2T doesn’t have a screen, so I thought it would be useful to signal that the picture has been taking by playing a simple mp3 file. I recorded a toot sound to a file called toot.mp3 and saved that to the folder where we can run the code below from.

Pydub is a library for playing back sounds using Python. It can do a lot more than this, but it was the simplest, cross-platform library I could find.

from pydub import AudioSegment
from pydub.playback import play

def play_toot_sound():
    """ Play toot sound """
    song = AudioSegment.from_mp3('toot.mp3')


Putting it all together

I’ve created a python script and some libraries of my own to manage all the different parts above.

This project is called Duckface after the silly face people used to pull when taking Instagram photos.

You can find the source code here:

An example image taken with duckface

Did you find this content useful?

If you found this high quality content useful please consider supporting my work, so I can continue to create more content for you.

I give away all my content for free: Weekly video content on YouTube, 3d Printable designs, Programs and Code, Reviews and Project write-ups, but 98% of visitors don't give back, they simply read/watch, download and go. If everyone who reads or watches my content, who likes it, helps fund it just a little, my future would be more secure for years to come. A price of a cup of coffee is all I ask.

There are a couple of ways you can support my work financially:

If you can't afford to provide any financial support, you can also help me grow my influence by doing the following:

Thank you again for your support and helping me grow my hobby into a business I can sustain.
- Kevin McAleer