Special thanks to RasTacsko for Militech Boot animation: (Screen used: waveshare oled/lcd)
Now you can add boot animations to your Pwnagotchi! I created this project while building a Cyberpunk-themed Pwnagotchi for myself. I will be releasing a complete set as soon as it's finished. This guide will walk you through the process step-by-step.
- π§ Pwnagotchi setup on Raspberry Pi
- π A Supported Screen, list can be found here
- π SSH access to your Pwnagotchi device
- Tested on Jays image
Open a terminal and SSH into your Pwnagotchi device:
ssh pi@ip_address
Transfer the boot image from your local machine to the Pwnagotchi device:
scp /path/to/your/frames/* [email protected]:/home/pi/
Create a directory for the boot animation images and move the images there:
sudo mkdir -p /usr/local/bin/boot_animation_images
sudo mv /home/pi/*.png /usr/local/bin/boot_animation_images/
Update the fonts.py
file to ensure proper font settings. Directly copy-paste in terminal:
sudo tee /usr/local/lib/python3.11/dist-packages/pwnagotchi/ui/fonts.py > /dev/null << EOF
from PIL import ImageFont
# should not be changed
FONT_NAME = 'DejaVuSansMono'
# can be changed
STATUS_FONT_NAME = None
SIZE_OFFSET = 0
Bold = None
BoldSmall = None
BoldBig = None
Medium = None
Small = None
Huge = None
def init(config):
global STATUS_FONT_NAME, SIZE_OFFSET
STATUS_FONT_NAME = config.get('ui', {}).get('font', {}).get('name', FONT_NAME)
SIZE_OFFSET = config.get('ui', {}).get('font', {}).get('size_offset', SIZE_OFFSET)
setup(10, 8, 10, 25, 25, 9)
def status_font(old_font):
global STATUS_FONT_NAME, SIZE_OFFSET
if STATUS_FONT_NAME is None:
STATUS_FONT_NAME = FONT_NAME # Fallback to default font if not set
return ImageFont.truetype(STATUS_FONT_NAME, size=old_font.size + SIZE_OFFSET)
def setup(bold, bold_small, medium, huge, bold_big, small):
global Bold, BoldSmall, Medium, Huge, BoldBig, Small, FONT_NAME
Small = ImageFont.truetype(FONT_NAME, small)
Medium = ImageFont.truetype(FONT_NAME, medium)
BoldSmall = ImageFont.truetype(f"{FONT_NAME}-Bold", bold_small)
Bold = ImageFont.truetype(f"{FONT_NAME}-Bold", bold)
BoldBig = ImageFont.truetype(f"{FONT_NAME}-Bold", bold_big)
Huge = ImageFont.truetype(f"{FONT_NAME}-Bold", huge)
EOF
Create a script to display the boot animation. Make sure to replace the import and the initialize
function with the correct screen type you are using:
The current code below is for the Waveshare 2.13 V4 screen, but you can change the screen type by following the guide below:
Visit this link Screen type and then select the file with your screen name, replace the ones as shown below:
-
Import the correct screen type:
- The line
from pwnagotchi.ui.hw import waveshare2in13_V4
should be replaced with the import corresponding to your specific screen type.
- The line
-
Update the class definition:
- The class name
CustomWaveshareV4
and its parent classwaveshare2in13_V4.WaveshareV4
should be updated to match the correct screen type.
- The class name
-
Modify the
initialize
function:- The line
from pwnagotchi.ui.hw.libs.waveshare.epaper.v2in13_V4.epd2in13_V4 import EPD
should be updated based on your screen type.
- The line
-
Update the display type in the
config
dictionary:- The line
'type': 'ws4'
should be updated to match your screen type, find your screen code here
- The line
Directly copy-paste in terminal:
sudo tee /usr/local/bin/boot_animation.py > /dev/null << EOF
import time
from PIL import Image
from pwnagotchi.ui.hw import waveshare2in13_V4 # Change this import based on your screen type
import os
class CustomWaveshareV4(waveshare2in13_V4.WaveshareV4): # Change this based on your screen type
def __init__(self, config):
super().__init__(config)
def layout(self):
return None
def initialize(self):
from pwnagotchi.ui.hw.libs.waveshare.epaper.v2in13_V4.epd2in13_V4 import EPD # Change this based on your screen type
self._display = EPD()
self._display.init()
self._display.Clear(0xFF) # Clear to white
def render(self, canvas):
buf = self._display.getbuffer(canvas)
self._display.displayPartial(buf)
def clear(self):
self._display.Clear(0xFF) # Clear to white
def show_boot_animation():
config = {
'ui': {
'display': {
'type': 'ws4', # Change this based on your screen type
'color': 'black'
}
}
}
display = CustomWaveshareV4(config)
display.initialize()
width, height = 250, 122 # Dimensions of the 2.13 inch display
# Path to the boot animation frames
frames_path = '/usr/local/bin/boot_animation_images/'
# Ensure at least 3 loops within the 5-second duration
min_loops = 3
total_duration = 5
start_time = time.time()
loop_count = 0
try:
while (time.time() - start_time < total_duration) or (loop_count < min_loops):
# Get all PNG files in the directory
frames = sorted([f for f in os.listdir(frames_path) if f.endswith('.png')])
for frame in frames:
if (time.time() - start_time >= total_duration) and (loop_count >= min_loops):
break
with Image.open(os.path.join(frames_path, frame)) as img:
img = img.resize((width, height)).transpose(Image.FLIP_TOP_BOTTOM).transpose(Image.FLIP_LEFT_RIGHT).convert('1') # Resize, flip vertically and horizontally, and convert to 1-bit color
display.render(img)
time.sleep(0.167) # Adjust this value to control animation speed
loop_count += 1
except Exception as e:
print(f"An error occurred: {str(e)}")
display.clear() # Only clear if an exception occurs
if __name__ == "__main__":
show_boot_animation()
EOF
Make the boot animation script executable:
sudo chmod +x /usr/local/bin/boot_animation.py
Run the boot animation script to test it:
sudo python3 /usr/local/bin/boot_animation.py
Edit the Pwnagotchi launcher file to include the boot animation script:
sudo tee /usr/bin/pwnagotchi-launcher > /dev/null << EOF
#!/usr/bin/env bash
source /usr/bin/pwnlib
# Run boot animation
/usr/bin/python3 /usr/local/bin/boot_animation.py
# we need to decrypt something
if is_crypted_mode; then
while ! is_decrypted; do
echo "Waiting for decryption..."
sleep 1
done
fi
if is_auto_mode; then
/usr/local/bin/pwnagotchi
systemctl restart bettercap
else
/usr/local/bin/pwnagotchi --manual
fi
EOF
Make the launcher script executable:
sudo chmod +x /usr/bin/pwnagotchi-launcher
Reload the systemd manager configuration:
sudo systemctl daemon-reload
Restart Pwnagotchi to apply the changes:
sudo systemctl restart pwnagotchi
https://www.reddit.com/r/pwnagotchi/comments/1ej5fsl/cyberpunk_rebecca_x_pwnagotchi_update_1/
Feel free to replace these placeholders with actual frames from your boot animation to give a visual preview.
Enjoy your new boot animation! π Your Pwnagotchi is now even more personalized and stylish.
- Open Photoshop and create a new project.
- If you don't have photoshop use Photopea
- Set the dimensions to match your screen resolution (e.g., 250x122 pixels for Waveshare 2.13 V4).
- Design each frame of your animation.
- Make the color of the image black and white which can be done using photoshop with one click, adjust the level of darkness according to yourself.
- Keep each frame as a separate layer or save each frame as a separate file.
- Ensure the background is black or white.
- Export each frame as a PNG file.
- Go to
File > Export > Export As
. - Choose PNG as the format.
- Save each frame with a sequential naming convention (e.g., frame001.png, frame002.png, etc.).
- Go to
- Transfer the exported frames to your Pwnagotchi device using the SCP command provided in step 2 above.
- Ensure the
boot_animation.py
script points to the directory containing your new frames.
- Run the boot animation script to test your animation.
- Refine your frames in Photoshop as needed and re-export until you achieve the desired effect.
By following these steps, you can create and implement custom boot animations to give your Pwnagotchi a unique and personalized touch.