A comprehensive browser-based image metadata extraction tool built entirely in Rust using Yew framework. See ROADMAP.md for the planned feature roadmap.
This application allows users to upload images and extract comprehensive metadata with advanced visualization, export capabilities, and privacy-focused image cleaning:
- EXIF data: Camera settings, timestamps, camera model, lens info, etc.
- GPS coordinates: Location data with Google Maps, Apple Maps, and OpenStreetMap links
- GPS privacy controls: Degrade coordinate precision for privacy (street, neighborhood, city, region levels)
- One-click map links: Copy map URLs to clipboard without opening tabs
- Image dimensions: Width, height, and technical specifications
- File information: Size, format, and basic properties
- Categorized display: Organized by Camera Settings, GPS, Technical, etc.
- Comprehensive coverage: All standard EXIF tags and values
- Smart explanations: Toggle-able descriptions for each metadata field
- Auto-select on upload: All metadata fields are selected by default
- Batch processing: Upload multiple files with progress tracking and navigation
- ZIP archive support: Extract and process entire archives of images in one upload
- Smart thumbnails: Compact 300x200px display for better page layout
- Click-to-expand: Full-screen modal view for detailed inspection
- Responsive design: Works seamlessly across different screen sizes
- Metadata removal: Strip ALL EXIF data, GPS, and camera information
- Format conversion: Convert between JPEG and PNG regardless of input format
- Quality control: Adjustable JPEG compression (30%-100%)
- Binary metadata removal: Lossless cleaning for JPEG, PNG, WebP, GIF and more
- One-click download: Privacy-safe images with zero metadata
- Batch ZIP download: Clean multiple images and download as a single ZIP archive
- Selective export: Choose exactly which metadata fields to include
- Multiple formats: JSON, CSV, Text, Markdown, YAML, and XML
- Copy to clipboard: Instant copy for all formats without downloading files
- Export profiles: Save and load custom metadata selection patterns
- Quick profiles: Pre-configured presets for common use cases:
- Journalism: Essential metadata for news and photojournalism
- Real Estate: Basic info without sensitive location data
- Forensics: Complete metadata for analysis and verification
- Privacy-Safe: Only basic file info without identifying metadata
- Research/Technical: Camera settings and technical specifications
- Custom profiles: Save your own selection patterns with descriptions
- Profile management: Load, save, and delete custom export profiles
- File info options: Toggle filename, size, and dimensions
- Smart filtering: Visual checkboxes for granular control
- Batch combined export: Export all loaded files in a single JSON array, CSV table, or concatenated TXT report
- Auto-generated filenames: Convenient downloads with descriptive names
- Select/deselect all: Quickly toggle entire metadata sets
- Disabled export when empty: Buttons stay inactive until something is selected
- Professional formats: YAML and XML for enterprise and research workflows
- Command palette: Keyboard-driven interface for power users
- Organized metadata: Alphabetically sorted categories and fields
- Stable rendering: No more jumping sections during UI updates
- Modular components: Clean, maintainable component architecture
- Professional styling: Color-coded sections with intuitive icons
- Dark mode support: Automatic system theme detection and manual toggle
- Batch navigation: Previous/Next buttons for switching between uploaded files
Cmd/Ctrl + K
: Open the command paletteCmd/Ctrl + O
: Open file dialogSpace
: Expand/collapse image view?
: Toggle explanationsCmd/Ctrl + A
: Select all metadataCmd/Ctrl + D
: Deselect all metadataCmd/Ctrl + 1
: Export as JSONCmd/Ctrl + 2
: Export as CSVCmd/Ctrl + 3
: Export as TextCmd/Ctrl + Shift + 1
: Copy as JSONCmd/Ctrl + Shift + 2
: Copy as CSVCmd/Ctrl + Shift + 3
: Copy as Text
- SHA-256 file hashing: Cryptographic fingerprints for file integrity verification
- Provenance tracking: Unique file identifiers for chain of custody
- Duplicate detection: Automatic identification of identical files in batch uploads
- Visual duplicate warnings: Clear UI alerts showing duplicate file groups
- Privacy risk scoring: Automatic privacy assessment with risk levels (Low, Medium, High, Critical)
- Sensitive field detection: Identifies GPS coordinates, camera serial numbers, owner names, and timestamps
- Privacy warnings: Detailed explanations of privacy risks for each sensitive metadata field
- Metadata consistency checks: Automatic validation of metadata integrity
- Timestamp inconsistencies (DateTime vs DateTimeOriginal)
- GPS reference field validation (N/S/E/W indicators)
- Dimension field mismatches (detects resizing)
- Incomplete metadata patterns
- Visual warnings for detected anomalies
- Risk-based recommendations: Actionable guidance for protecting privacy before sharing
- Privacy-first forensics: All analysis performed locally in the browser
- Export integrity: Hash values included in metadata exports for verification
Key Features:
- 🔒 Complete privacy: Runs entirely in the browser (no server required)
- 🧹 Metadata cleaning: Remove all tracking data for privacy
- ⚡ High performance: Fast processing via WebAssembly
- 🌐 Universal compatibility: Works in any modern web browser
- 📱 Responsive design: Mobile and desktop friendly
- 🎨 Professional UI: Clean, intuitive interface with visual hierarchy
- 🔧 Format flexibility: Convert between image formats while cleaning
- 🔍 Forensic analysis: SHA-256 file hashing for provenance and deduplication
- 🦀 Rust: Memory-safe systems programming language
- 🕸️ WebAssembly: High-performance web execution
- ⚛️ Yew: Modern React-like framework for Rust
- 📦 wasm-pack: Rust-generated WebAssembly packaging
kamadak-exif
: Comprehensive EXIF metadata parsingimage
: Image format support and dimension extractionserde
: Serialization for JSON export functionalityweb-sys
: Browser API bindings for file handling and canvas operations
- 🔧 Single Language: Rust throughout the entire application
- ⚡ Performance: Near-native speed via WebAssembly
- 🛡️ Safety: Memory-safe image parsing prevents crashes
- 📦 Small Bundle: Optimized WASM output
- 🌐 Universal: Runs in any modern web browser
- 🧩 Modular: Component-based architecture for maintainability
- Rust + WASM: Combines safety with performance for binary data processing
- Client-Side: Complete privacy - no server communication required
- Modern Web: Leverages cutting-edge web technologies
- Developer Experience: Type safety and excellent tooling throughout
- Rust: Install via rustup.rs
- Rustfmt & Clippy: Automatically installed via
rust-toolchain.toml
on firstcargo
run - wasm-pack: Install with
cargo install wasm-pack
- HTTP Server: Node.js for
npx
(recommended) or Python forhttp.server
-
Clone the repository:
git clone https://github.com/akofink/image-metadata-extractor.git cd image-metadata-extractor
-
Set up development environment:
# Install pre-commit hooks for code quality make setup-hooks # Check dependencies (installs clippy/rustfmt on first run) make check
-
Build and serve:
# Development build and serve make && make serve # Or production build make build-release
-
Open in browser: Navigate to
http://localhost:8000
The project includes a comprehensive Makefile for streamlined development:
make
ormake build
- Development build (fast, with debug info)make build-release
- Production build (optimized, smaller size)make serve
- Start local development server on port 8000make setup-hooks
- Install git pre-commit hooks for code quality
make check
- Check code compilationmake test
- Run all testsmake coverage
- Generate HTML coverage reportmake format
- Format code with cargo fmtmake lint
- Run clippy lintingmake clean
- Clean build artifacts
make dev
- Full development workflow (check + format + lint + build)make prod
- Production workflow (check + test + lint + format + build-release)make help
- Show all available commands
For consistent code quality, install git pre-commit hooks:
make setup-hooks
This automatically runs code checks, formatting, linting, test separation checks, an enforced coverage threshold (configurable via COVERAGE_MIN, default 60%), and security/dependency policy checks (cargo-audit, cargo-deny) on every commit.
In CI, the Quality Gate workflow repeats these checks for pull requests, ensuring a consistent bar before merge.
├── src/
│ ├── app.rs # Main application component
│ ├── components/ # Modular UI components
│ │ ├── file_upload.rs # File selection and processing
│ │ ├── image_display.rs # Image viewing and file info
│ │ ├── metadata_display.rs # EXIF data with categorization
│ │ ├── image_cleaner.rs # Privacy-safe image downloads
│ │ └── metadata_export.rs # Export functionality
│ ├── exif.rs # EXIF metadata extraction logic
│ ├── export.rs # CSV and text export functions
│ ├── image_cleaner.rs # Image metadata removal via canvas
│ ├── metadata_info.rs # Field explanations and categorization
│ ├── types.rs # Data structures and filtering
│ ├── utils.rs # File downloads and utilities
│ └── lib.rs # WebAssembly exports and entry point
├── pkg/ # Generated WebAssembly files (git-ignored)
├── index.html # Web application entry point
├── Makefile # Development commands and workflows
├── Cargo.toml # Rust dependencies and configuration
├── CLAUDE.md # Development documentation for AI assistance
└── README.md # This documentation
-
Clone and setup:
git clone https://github.com/akofink/image-metadata-extractor.git cd image-metadata-extractor make setup-hooks # Install code quality hooks make check # Verify toolchain and dependencies
-
Build and serve:
make && make serve
-
Open browser: Navigate to
http://localhost:8000
-
Upload and explore:
- Upload an image using the file input
- View extracted metadata organized by category
- Toggle field explanations for detailed information
- Select specific metadata fields for export
- Download privacy-safe cleaned images
- Export metadata in JSON, CSV, or text format
- JPEG/JPG: Full EXIF support including GPS data
- PNG: Basic metadata and dimensions
- GIF: Dimensions and file information
- WebP: Modern format with metadata support
- ZIP: Extract and process all images from ZIP archives
- Batch extraction: Automatically detects and processes all image files within archives
- Progress tracking: Real-time progress updates during archive extraction
- JSON: Structured data with nested objects for complex metadata
- CSV: Tabular format perfect for spreadsheet analysis
- TXT: Human-readable reports with organized sections
- JPEG: Adjustable quality (30%-100%) for size optimization
- PNG: Lossless format for maximum quality retention
- WebP: Modern format for smaller file sizes
- GIF: Basic format for simple animations or compatibility
- Format conversion: Input JPEG/PNG/GIF/WebP → Output JPEG/PNG/GIF/WebP
- Camera Information: Make, model, lens details
- Shooting Parameters: ISO, aperture, shutter speed, focal length
- Timestamps: Creation date, modification date
- GPS Location: Latitude, longitude with Google Maps, Apple Maps, and OpenStreetMap links
- Technical Details: Color space, orientation, resolution
- Software Information: Camera firmware, editing software
- Organized categories: Alphabetically sorted for consistent display
- Complete metadata removal: Strips ALL EXIF data, GPS coordinates, and camera information
- Canvas-based processing: Uses HTML5 Canvas API for reliable metadata removal
- Format flexibility: Convert between JPEG and PNG during cleaning
- Quality control: Adjustable JPEG compression for size vs. quality balance
- Binary metadata removal: Lossless cleaning for JPEG, PNG, WebP, GIF and more
- One-click downloads: Browser-native downloads with cleaned filenames
- Batch cleaning: Download all uploaded images as a ZIP archive with metadata removed
- Granular selection: Choose individual metadata fields with checkboxes
- Smart filtering: Include/exclude file info and GPS data separately
- Multiple formats: JSON for developers, CSV for analysis, TXT for reports
- Export profiles: Save and load custom metadata selection patterns for repeatable workflows
- Quick profiles: Instantly apply pre-configured selections for common use cases (journalism, real estate, forensics, privacy-safe, research)
- Custom profiles: Create and save your own selection patterns with descriptive names
- Profile persistence: All profiles stored locally in browser for instant access
- Real-time preview: See field count and selection status
- Auto-generated filenames: Descriptive names based on original filename
- Select/deselect all: Toggle all fields globally or by category
- Disabled export when empty: Buttons enable only when something is selected
- Component architecture: Modular, maintainable codebase
- Responsive design: Works seamlessly on mobile and desktop
- Professional styling: Color-coded sections with intuitive icons
- Stable rendering: Alphabetically sorted categories prevent UI jumping
- Accessibility: Keyboard navigation and screen reader friendly
- Client-Side Only: No data leaves your browser - complete privacy
- Fast Processing: Rust + WebAssembly optimization for near-native speed
- Memory Efficient: Handles large images smoothly without crashes
- Instant Results: Real-time metadata extraction and processing
- Canvas optimization: Efficient image processing for metadata removal
The project uses Playwright for cross-browser end-to-end testing.
Prerequisites:
# Install dependencies (first time only)
npm install
# Install Playwright browsers (first time only)
npx playwright install
Run tests:
# Run all tests (headless)
npm run test:e2e
# Run with UI mode (recommended for development)
npm run test:e2e:ui
# Run in headed mode (see the browser)
npm run test:e2e:headed
# Debug a specific test
npm run test:e2e:debug
# Run tests for a specific browser
npm run test:e2e:chromium
npm run test:e2e:firefox
npm run test:e2e:webkit
Test Structure:
tests/e2e/
- E2E test filestests/e2e/fixtures/
- Test image filesplaywright.config.ts
- Playwright configuration
Best Practices:
- Tests run in parallel across browsers (Chrome, Firefox, Safari, Mobile)
- Screenshots and videos captured on failure for debugging
- Web server automatically started before tests
- See Playwright Best Practices for more
- All commits automatically run pre-commit hooks (install with
make setup-hooks
) - Code must pass
cargo check
,cargo fmt
, andcargo clippy
- Use the Makefile commands for consistent development workflows
- CI publishes an HTML coverage report for each pull request
- Follow the modular component architecture established in
src/components/
- E2E tests must pass for all supported browsers
- Install pre-commit hooks:
make setup-hooks
- Install E2E test dependencies:
npm install
- Use
make dev
for the full development workflow - Run E2E tests:
npm run test:e2e:ui
(recommended during development) - Use
make prod
before submitting pull requests - All changes are automatically formatted and linted on commit
The project maintains high code quality standards through automated tooling, comprehensive pre-commit checks, and end-to-end testing.