Skip to content

FireAndIceFrog/StringArtGenerator

Repository files navigation

🎨 String Art Generator - WebAssembly + React

A real-time string art generator that converts images into beautiful string art patterns. Built with Rust compiled to WebAssembly for high-performance image processing, and React for an interactive web interface.

✨ Features

  • Real-time Generation: Watch string art being created line by line
  • WebAssembly Performance: Fast image processing using Rust compiled to WASM
  • Interactive UI: Drag & drop image upload with live preview
  • Multiple Quality Presets: Fast, Balanced, and High Quality modes
  • Real-time Progress: Live updates showing generation progress
  • Canvas Visualization: Interactive canvas with string path visualization
  • Image Comparison: Toggle between original image and string art result

πŸ—οΈ Architecture

Rust WASM Module (StringArtRustImpl/)

  • Core Algorithm: Greedy string art path generation
  • Image Processing: Advanced preprocessing with subject extraction, shadow removal
  • WASM Interface: Streaming progress callbacks for real-time updates
  • Configuration: Flexible configuration system with presets

React Frontend (string-art-demo/)

  • Modern React: TypeScript, Hooks, and functional components
  • Real-time Updates: Live canvas updates during generation
  • Responsive Design: Mobile-friendly interface
  • Progress Tracking: Detailed progress information with completion percentage

πŸš€ Quick Start

Prerequisites

  • Rust (latest stable)
  • Node.js (v20.19.0+ or v22.12.0+)
  • wasm-pack (install with cargo install wasm-pack)

Installation

  1. Clone the repository

    git clone <your-repo-url>
    cd StringArt
  2. Install React dependencies

    cd string-art-demo
    npm install
    cd ..
  3. Build the WASM package

    ./build-wasm.sh
  4. Start the development server

    cd string-art-demo
    npm run dev
  5. Open your browser Navigate to http://localhost:5173

πŸ”§ Development

Building WASM Module

The WASM module is built using wasm-pack with the following command:

cd StringArtRustImpl
wasm-pack build --target web --features wasm --out-dir ../string-art-wasm

Or use the provided build script:

./build-wasm.sh

Project Structure

StringArt/
β”œβ”€β”€ StringArtRustImpl/          # Rust WASM module
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ lib.rs             # Main library entry point
β”‚   β”‚   β”œβ”€β”€ wasm.rs            # WASM interface and bindings
β”‚   β”‚   β”œβ”€β”€ greedy_generator.rs # Core string art algorithm
β”‚   β”‚   β”œβ”€β”€ image_processing.rs # Image preprocessing
β”‚   β”‚   └── ...
β”‚   └── Cargo.toml             # Rust dependencies
β”œβ”€β”€ string-art-demo/           # React frontend
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ App.tsx            # Main React component
β”‚   β”‚   β”œβ”€β”€ hooks/
β”‚   β”‚   β”‚   └── useStringArt.ts # WASM integration hook
β”‚   β”‚   └── components/
β”‚   β”‚       β”œβ”€β”€ ImageUploader.tsx
β”‚   β”‚       └── StringArtCanvas.tsx
β”‚   └── package.json           # Node.js dependencies
β”œβ”€β”€ build-wasm.sh             # Build script
└── README.md                 # This file

WASM Interface

The Rust code exposes these main interfaces to JavaScript:

// Main string art generator
#[wasm_bindgen]
pub struct StringArtWasm {
    // ... implementation
}

#[wasm_bindgen]
impl StringArtWasm {
    #[wasm_bindgen(constructor)]
    pub fn new(image_data: &[u8], config: Option<WasmStringArtConfig>) -> Result<StringArtWasm, JsValue>;
    
    pub fn generate_path_streaming(
        &mut self,
        max_lines: usize,
        line_darkness: f64,
        min_improvement_score: f64,
        progress_callback: &js_sys::Function,
    ) -> Result<Vec<usize>, JsValue>;
    
    pub fn get_nail_coordinates(&self) -> Vec<JsValue>;
    // ... more methods
}

Configuration Options

interface StringArtConfig {
  num_nails: number;              // Number of nails around the circle
  image_size: number;             // Target image size for processing
  extract_subject: boolean;       // Extract main subject from background
  remove_shadows: boolean;        // Remove shadows from the image
  preserve_eyes: boolean;         // Preserve eye details
  preserve_negative_space: boolean; // Preserve negative space
  negative_space_penalty: number; // Penalty for drawing in negative space
  negative_space_threshold: number; // Threshold for negative space detection
}

Presets

  • Fast: 360 nails, basic processing (quick results)
  • Balanced: 720 nails, full processing (good quality/speed balance)
  • High Quality: 1440 nails, full processing (best quality)

πŸ§ͺ Usage

  1. Upload an Image: Drag and drop or click to select an image file
  2. Choose Quality: Select from Fast, Balanced, or High Quality presets
  3. Generate: Click "Generate String Art" to start the process
  4. Watch Progress: Monitor real-time progress with live canvas updates
  5. View Results: Toggle between original image and string art result

πŸ”¨ Implementation Details

Algorithm

  • Greedy Path Finding: Iteratively selects the next nail that maximizes improvement
  • Image Preprocessing: Subject extraction, shadow removal, contrast enhancement
  • Real-time Updates: Streaming progress callbacks for live visualization

Performance

  • WASM Compilation: Rust compiled to WebAssembly for near-native performance
  • Streaming Results: Real-time path updates without blocking the UI
  • Efficient Canvas: Optimized canvas rendering for smooth animations

Browser Compatibility

  • Modern browsers with WebAssembly support
  • Chrome, Firefox, Safari, Edge (latest versions)

πŸ“ API Reference

React Hook: useStringArt

const {
  wasmModule,           // Loaded WASM module
  isLoading,           // Loading state
  error,               // Error state
  generateStringArt,   // Function to generate string art
  presets,             // Configuration presets
} = useStringArt();

Progress Callback

interface ProgressInfo {
  lines_completed: number;     // Number of lines completed
  total_lines: number;         // Total number of lines to generate

   pub current_path: number[], //All completed lines till now
  score: number;               // Current improvement score
  completion_percent: number;  // Completion percentage (0-100)
  path_segment: [number, number]; // Current path segment
}

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • Inspired by the mathematical beauty of string art
  • Built with modern web technologies for educational and artistic purposes
  • Thanks to the Rust and WebAssembly communities for excellent tooling

πŸ› Troubleshooting

Common Issues

  1. WASM Module Not Loading

    • Ensure you've built the WASM package: ./build-wasm.sh
    • Check browser console for CORS or loading errors
  2. Build Errors

    • Verify Rust and wasm-pack are installed
    • Update dependencies: cargo update and npm update
  3. Performance Issues

    • Try the "Fast" preset for quicker results
    • Ensure your browser supports WebAssembly

Development Tips

  • Use browser dev tools to monitor WASM module loading
  • Check the Network tab for WASM file loading issues
  • Use the Console to see progress callback outputs

πŸ“§ Support

For questions, issues, or contributions, please open an issue on GitHub or contact the maintainers.


Happy String Art Creating! 🎨

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

No packages published