Create stunning optical illusion images with hidden text that appears when viewed at an angle!
Pyedgeon is a Python library that generates circular images containing text that's hidden when viewed directly but becomes readable when the image is tilted and viewed nearly edge-on. This effect is created using circular anamorphic distortion - a mathematical transformation that compensates for perspective foreshortening.
The solution to the above illusion is "NPR COOL DAD ROCK" ;)
Tip: View generated images on a mobile device or tablet for the best experience - you can easily tilt the device to see the hidden message!
Install via pip:
pip install pyedgeonPyedgeon requires a TrueType font (.ttf) or TrueType Collection (.ttc) to render text. The library will automatically search for and use system fonts, so in most cases you don't need to do anything!
Supported Platforms:
- ✅ macOS: Automatically finds Helvetica or Helvetica Neue
- ✅ Linux: Automatically finds DejaVu Sans or Liberation Sans
- ✅ Windows: Automatically finds Arial or Calibri
If you want to use a specific font, simply provide the font_path parameter:
img = Pyedgeon(
illusion_text="HELLO",
font_path="/path/to/your/font.ttf" # Use your preferred font
)Finding Fonts on Your System:
- macOS:
/System/Library/Fonts/or/Library/Fonts/ - Linux:
/usr/share/fonts/truetype/ - Windows:
C:\Windows\Fonts\
When testing this package I've found better success with lighter fonts. Personally I think that pyedgeon buttons look best with the DejaVuSans-ExtraLight.ttf font (not distributed), but it's easy to find and install this font and specify the path to it in the API.
The quickest way to create an image is using the included example script:
# Clone the repository
git clone https://github.com/abehmiel/pyedgeon.git
cd pyedgeon
# Install dependencies
make install
# Create a default "HELLO WORLD" image
make example
# Or customize the message
make example MESSAGE="SECRET TEXT"You can also run the script directly for more options:
# Basic usage
python scripts/example.py
# Custom message
python scripts/example.py "YOUR MESSAGE"
# Specify custom font
python scripts/example.py "YOUR MESSAGE" --font /path/to/font.ttf
# Custom output filename
python scripts/example.py "YOUR MESSAGE" --output my_image.png
# See all options
python scripts/example.py --helpfrom pyedgeon import Pyedgeon
# Create an illusion image with default settings
img = Pyedgeon(illusion_text="HELLO WORLD")
img.create()
# Creates: HELLO WORLD.png in current directoryThat's it! The image will be saved in your current working directory.
from pyedgeon import Pyedgeon
img = Pyedgeon(
illusion_text="CUSTOM TEXT", # Text to display (auto-uppercase by default)
# font_path="/path/to/font.ttf", # Optional: custom font (auto-detected if omitted)
num_rotations=6, # Number of text rotations (default: 6)
img_side=2048, # Image size in pixels (default: 1024)
text_color=(255, 0, 0), # RGB color for text (default: black)
background_color=(255, 255, 255), # RGB color for background (default: white)
file_path="/output/directory/", # Output directory (default: current dir)
file_name="my_illusion", # Output filename (default: illusion_text)
file_ext=".png", # File format (default: .png)
charmax=22, # Max characters (default: 22)
upper_case=True # Convert to uppercase (default: True)
)
img.create()| Parameter | Type | Default | Description |
|---|---|---|---|
illusion_text |
str | "HELLO WORLD" | Text to display in the illusion |
font_path |
str | None | Path to TrueType font file (auto-detected if None) |
num_rotations |
int | 6 | Number of text rotations around circle |
img_side |
int | 1024 | Size of square image in pixels |
text_color |
tuple | (0, 0, 0) | RGB color for text (0-255) |
background_color |
tuple | (255, 255, 255) | RGB color for background (0-255) |
file_path |
str | "" | Directory path for output (empty = current dir) |
file_name |
str | None | Output filename without extension (None = use text) |
file_ext |
str | ".png" | File format extension |
charmax |
int | 22 | Maximum character limit |
crop_width_x |
int | 14 | Horizontal padding for text bounding box |
crop_width_y |
int | 5 | Vertical padding for text bounding box |
darkness_threshold |
int | 116 | Threshold for black/white conversion (0-255) |
upper_case |
bool | True | Automatically convert text to uppercase |
For detailed parameter descriptions, see API_REFERENCE.md.
- Mobile/Tablet: Best viewing experience - tilt device to nearly edge-on
- Desktop: Hold screen at eye level and view from an extreme angle
- Print: Works great on physical prints - hold at eye level and tilt
- Text Length: Keep text between 15-22 characters for best results
- Font Choice: Extra-light or light weight fonts work best
- Colors: High contrast between text and background recommended
- Image Size: Use 1024 for web display, 2048+ for printing
- Rotations: 6-8 rotations provide good visibility from multiple angles
The generated image is available in memory after creation:
img = Pyedgeon(illusion_text="HELLO")
img.create()
# Access the PIL Image object
pil_image = img.full_image
# Perform additional operations
pil_image.show() # Display in image viewer
pil_image.resize((512, 512)) # Resize
pil_image.save("copy.png") # Save additional copyComprehensive documentation is available:
- API_REFERENCE.md - Detailed API documentation with examples
- CLAUDE.md - Developer documentation, architecture, and algorithms
- SECURITY.md - Security guidelines for safe usage
- CONTRIBUTING.md - Guide for contributors
- DOCSTRING_EXAMPLES.md - Enhanced docstring examples
Contributions are welcome! Please see CONTRIBUTING.md for:
- Development setup
- Code guidelines
- Testing requirements
- Pull request process
- Priority areas for contribution
pyedgeon-service - A web service that uses this API to generate illusions online!
MIT License - see LICENSE file for details
Abraham Hmiel (abehmiel@gmail.com)
Special thanks to all contributors and users of this library!
