Skip to content

fabboe/offline-portrait-cropper

Repository files navigation

Offline Portrait Cropper

A Progressive Web App (PWA) that automatically detects faces and crops photos to head-and-shoulders portraits. Works offline after initial load.

Deployed at https://fabboe.github.io/offline-portrait-cropper/

Features

  • Automatic Face Detection: Uses TensorFlow.js BlazeFace model for accurate face detection
  • Smart Cropping: Automatically crops to include head and shoulders with a fixed 3:4 aspect ratio
  • Manual Fine-Tuning: Adjust the automatic crop with Cropper.js drag-and-drop interface
  • Offline Support: Full PWA with service worker - works without internet after first load
  • Drag & Drop: Easy-to-use interface with drag-and-drop file upload
  • High Quality Output: Exports 800×1000px portraits optimized for profile photos
  • Privacy First: All processing happens locally in your browser - no server uploads

Tech Stack

  • Framework: Vanilla JavaScript (ES modules)
  • Build Tool: Vite
  • Face Detection: TensorFlow.js + BlazeFace model
  • Image Processing: HTML5 Canvas API
  • Manual Cropping: Cropper.js
  • PWA: Vite PWA Plugin with Workbox

Quick Start

Prerequisites

  • Node.js 18+ and npm

Installation

  1. Clone or navigate to this repository:
cd offline-portrait-cropper
  1. Install dependencies:
npm install
  1. Start development server:
npm run dev
  1. Open your browser to the URL shown (typically http://localhost:5173)

Building for Production

Build the production-ready PWA:

npm run build

Preview the production build:

npm run preview

The built files will be in the dist/ directory, ready to deploy to any static hosting service.

How It Works

  1. Upload: Drag & drop a photo or click to upload
  2. Detection: BlazeFace model detects face location
  3. Auto-Crop: Automatically expands around face to include shoulders
  4. Aspect Ratio: Enforces 4:5 ratio (perfect for portraits)
  5. Fine-Tune (optional): Click "Fine-Tune Crop" to manually adjust the crop area
  6. Output: Renders 800×1000px high-quality portrait
  7. Download: Save as JPEG with one click

Deployment

Deploy to any static hosting service:

Vercel

npm install -g vercel
vercel

Netlify

npm install -g netlify-cli
netlify deploy --prod --dir=dist

GitHub Pages (Automated)

This project includes automatic GitHub Pages deployment!

See DEPLOY.md for detailed instructions.

Quick setup:

  1. Push your code to GitHub
  2. Enable GitHub Pages in Settings → Pages → Source: GitHub Actions
  3. Your site will automatically deploy on every push!

Your app will be live at: https://YOUR-USERNAME.github.io/offline-portrait-cropper/

Project Structure

offline-portrait-cropper/
├── index.html          # Main HTML with UI
├── app.js              # Core application logic
├── style.css           # Custom Cropper.js styles
├── vite.config.js      # Vite + PWA configuration
├── package.json        # Dependencies
├── public/             # Static assets
│   ├── icon.png        # PWA icons
│   ├── icon-192.png
│   └── icon-512.png
└── dist/               # Production build output

Configuration

Adjust Crop Region

Edit the expansion multipliers in app.js:107-110:

const horizontalExpand = 0.4;  // 40% on each side (wider/narrower)
const topExpand = 0.6;         // 60% above face (more/less headroom)
const bottomExpand = 1.2;      // 120% below face (more/less shoulders)

Change Aspect Ratio

Modify the target aspect ratio in app.js:120:

const targetAspect = 4 / 5;  // Current: 4:5 (portrait)
// Examples:
// 1 / 1        -> Square (1:1)
// 2 / 3        -> Classic portrait
// 3 / 4        -> Standard photo

Change Output Size

Adjust output dimensions in app.js:141-142:

const outputWidth = 800;   // Width in pixels
const outputHeight = 1000; // Height in pixels

Browser Support

  • Chrome/Edge 90+
  • Firefox 88+
  • Safari 14+
  • Opera 76+

All modern browsers with Canvas API and ES6 module support.

Offline Capabilities

After the first visit:

  • App shell cached (HTML, CSS, JS)
  • TensorFlow.js models cached
  • Works without internet connection
  • Install as app on mobile/desktop

Privacy & Security

  • No data collection: Zero analytics or tracking
  • Local processing: All images processed in your browser
  • No uploads: Images never leave your device
  • No storage: Images not saved (except when you download)

Performance Notes

  • First load: ~5-10s (downloads TensorFlow models ~8MB)
  • Subsequent loads: <1s (cached)
  • Processing time: 1-3s per image (depends on image size)
  • Model preloads on page load for faster first use

Troubleshooting

"No face detected" error:

  • Ensure face is clearly visible and well-lit
  • Face should be front-facing
  • Try a different photo

Slow performance:

  • Use smaller images (<5MB)
  • Clear browser cache and reload
  • Check if WebGL is enabled in browser

PWA not installing:

  • Must be served over HTTPS (or localhost)
  • Build production version: npm run build
  • Check browser DevTools > Application > Manifest

Usage Tips

Keyboard Shortcuts in Cropper

  • Arrow keys: Move crop box by 1 pixel
  • Shift + Arrow keys: Move crop box by 10 pixels

License

MIT License - Feel free to use for any purpose

Credits

About

offline browser tool to automatically crop the biggest face. with additional fine-tuning possibility

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors