Create pixel art and export Arduino-ready C++ code instantly
Pixel2CPP is a browser-based pixel art editor designed for Arduino and embedded display development. Draw your sprites, icons, and graphics, then export them as optimized C++ arrays ready to use with popular display libraries like Adafruit_GFX.
๐ฎ Try it live | ๐ Documentation | ๐ Report Issues
- ๐จ Intuitive Pixel Editor - Draw with pen, erase, fill, and eyedropper tools
- ๐ Smart Export Formats - Supports 6 different display formats with optimized data structures
- ๐ผ๏ธ Image Import - Load existing images and convert them to pixel art
- ๐ Professional Tools - Grid overlay, zoom, mirror drawing, undo/redo
- ๐งช Built-in Testing - Validate your exports with comprehensive format tests
- ๐ฑ Works Everywhere - Browser-based, no installation required
- โก Instant Code - Generate complete Arduino sketches, not just data arrays
- Open Pixel2CPP in your browser
- Set your canvas size to match your display
- Choose your export format (see Supported Formats)
- Start drawing your pixel art
- Click "Generate Code" to see the Arduino code
- Copy the code or download as
.h
file
# Clone the repository
git clone https://github.com/CodeRandomMC/pixel-to-cpp.git
cd pixel-to-cpp
# Install dependencies
npm install
# Start development server
npm run dev
# Open http://localhost:5173 in your browser
### Building for Production
```bash
# Build the project
npm run build
# Preview the production build
npm run preview
This project is configured to automatically deploy to GitHub Pages when you push to the main branch. The deployment is handled by GitHub Actions.
Manual Deployment:
- Build the project:
npm run build
- The built files will be in the
dist/
directory - Configure GitHub Pages in your repository settings to serve from the
dist/
directory - Or use the GitHub Actions workflow (recommended)
GitHub Pages URL: https://coderandommc.github.io/pixel-to-cpp
Canvas Size: Set width and height to match your display dimensions
- For SSD1306 OLED: 128x64 or 128x32
- For small TFT displays: 128x128, 160x80, 240x135
- For larger displays: 320x240, 480x320
Draw Mode: Choose the format that matches your display:
- 1-bit Horizontal/Vertical: For monochrome OLED displays (SSD1306, SH1106)
- RGB565: For color TFT displays (ST7735, ILI9341, ST7789)
- RGB888 24-bit: For high-quality displays with enough memory
- RGB888 32-bit: For displays supporting alpha transparency
- 1-bit Alpha: For transparency masks
Tool | Description | Usage |
---|---|---|
Pen | Draw pixels with primary color | Left-click to draw |
Erase | Remove pixels (set to transparent) | Left-click to erase |
Fill | Flood fill areas with color | Left-click to fill area |
Eyedropper | Pick colors from the canvas | Left-click to sample color |
Pro Tips:
- Right-click with any tool uses the secondary color
- Enable "Mirror X" or "Mirror Y" for symmetrical drawing
- Use the zoom slider for detailed work
- Toggle grid overlay for precise pixel placement
- Primary Color: Used with left-click
- Secondary Color: Used with right-click
- Color Picker: Click the color squares to choose new colors
- Swap Button: Quickly exchange primary and secondary colors
- Click "Upload Image" in the header
- Select any image file (PNG, JPG, GIF, etc.)
- The image will be automatically:
- Scaled to fit your canvas
- Centered on the canvas
- Converted to your chosen format (e.g., 1-bit for OLED displays)
- Name Your Asset: Enter a name in the text field (e.g., "player_sprite")
- Choose Output Format:
- Arduino Code: Complete sketch with setup() and display functions
- Plain Bytes: Just the data array with basic code
- Single Bitmap: Minimal array declaration
- GFX Bitmap Font: For use with Adafruit GFX font system
- Generate: Click "Generate Code" to see the result
- Copy or Download: Use "Copy Code" or "Export .h" buttons
Best for: OLED displays, e-ink, simple graphics Memory usage: 1 bit per pixel
// 64x32 sprite = 256 bytes
const uint8_t sprite_bits[] PROGMEM = { 0xFF, 0x81, 0x81, 0xFF, ... };
display.drawBitmap(x, y, sprite_bits, 64, 32, WHITE);
Best for: Color TFT displays, good balance of quality and memory Memory usage: 2 bytes per pixel
// 32x32 sprite = 2048 bytes
const uint16_t sprite_pixels[] PROGMEM = { 0xF800, 0x07E0, 0x001F, ... };
tft.drawRGBBitmap(x, y, sprite_pixels, 32, 32);
Best for: High-quality color displays with sufficient memory Memory usage: 3 bytes per pixel
// 32x32 sprite = 3072 bytes
const uint8_t sprite_pixels[] PROGMEM = { 255, 0, 0, 0, 255, 0, ... };
// Convert to RGB565 on-the-fly for display
Best for: Sprites with transparency, compositing Memory usage: 4 bytes per pixel
// 32x32 sprite = 4096 bytes
const uint8_t sprite_pixels[] PROGMEM = { 255, 0, 0, 255, 0, 255, 0, 128, ... };
// Includes alpha channel for transparency
Best for: Transparency masks, sprite masks Memory usage: 1 bit per pixel
const uint8_t sprite_alpha[] PROGMEM = { 0xFF, 0x00, 0x18, 0x7E, ... };
// Use for masking or transparency effects
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "my_sprite.h" // Generated by Pixel2CPP
Adafruit_SSD1306 display(128, 64, &Wire, -1);
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
// Draw your sprite at position (32, 16)
display.drawBitmap(32, 16, my_sprite_bits, my_sprite_w, my_sprite_h, WHITE);
display.display();
}
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include "my_sprite.h"
#define TFT_CS 10
#define TFT_RST 9
#define TFT_DC 8
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
void setup() {
tft.initR(INITR_BLACKTAB);
tft.fillScreen(ST77XX_BLACK);
// Draw RGB565 sprite
drawSprite(32, 32);
}
void drawSprite(int16_t x, int16_t y) {
tft.startWrite();
tft.setAddrWindow(x, y, my_sprite_w, my_sprite_h);
for (uint16_t i = 0; i < my_sprite_w * my_sprite_h; i++) {
tft.writePixel(pgm_read_word(&my_sprite_pixels[i]));
}
tft.endWrite();
}
Pixel2CPP includes a comprehensive test suite to validate your exports:
- Switch to the "Tests" tab
- Click "Run Tests"
- Verify all format conversions pass
The tests validate:
- โ 1-bit horizontal and vertical packing
- โ RGB565 color conversion accuracy
- โ RGB24 and RGB332 format correctness
- โ 4-bit grayscale conversion
- โ Alpha channel handling
- Use 1-bit for simple icons and text (smallest memory footprint)
- Use RGB565 for colorful sprites on TFT displays (good balance)
- Use RGB888 only when you have plenty of memory (ESP32, etc.)
- Horizontal packing is faster for most displays
- Vertical packing works better for column-oriented displays
- Pre-load sprites in PROGMEM to save RAM
- Use setAddrWindow() for fastest RGB565 drawing
- Design at actual pixel size for crisp results
- Use high contrast for 1-bit displays
- Test with your actual hardware - emulation isn't perfect
- Keep sprites small for Arduino Uno/Nano (limited memory)
- White export: Check your draw mode matches your display
- Wrong colors: Verify color format (RGB565 vs RGB888)
- Garbled display: Check byte order and display library compatibility
- Memory errors: Reduce sprite size or use more efficient format
- โจ Added RGB888 32-bit format with alpha channel support
- โจ Improved image import with automatic format conversion
- โจ Enhanced test suite with more comprehensive validation
- ๐ Fixed grid rendering on high-DPI displays
- ๐ Improved memory handling for large canvases
- ๐จ Updated UI with better tool organization
- โจ Added 1-bit alpha map export format
- โจ Added GFX Bitmap Font output format
- โจ Implemented mirror drawing modes (X and Y axis)
- โจ Added eyedropper tool for color picking
- ๐ Fixed undo/redo system edge cases
- ๐จ Improved responsive design for mobile devices
- ๐ Initial release
- โจ Core pixel editor with pen, erase, fill tools
- โจ Support for 1-bit, RGB565, RGB24, RGB332, and 4-bit grayscale
- โจ Image import functionality
- โจ Arduino code generation
- โจ Built-in testing framework
- ๐ฎ Animation frame support for sprites
- ๐ฎ Palette-based color modes
- ๐ฎ Advanced dithering algorithms
- ๐ฎ Batch export multiple sprites
- ๐ฎ Custom display library templates
Found a bug or have a feature request? We'd love to hear from you!
- ๐ Report bugs: Open an issue
- ๐ก Request features: Start a discussion
- ๐ง Submit pull requests: Fork, branch, and PR
- ๐ Improve docs: Help make this guide even better
MIT License - see LICENSE file for details.
Please respect the spirit of open source:
- โ Use freely for learning and personal projects
- โ Modify and improve for your own needs
- โ Share improvements with the community
- โ Do not sell this software or charge for its use
- โ Do not redistribute for commercial gain
Made with โค๏ธ by CodeRandom for the Arduino and embedded community.
Need help? Check out our examples directory or join the community discussions.