Initial implementation of Tilt-Shift Camera Android app

A dedicated camera app for tilt-shift photography with:
- Real-time OpenGL ES 2.0 shader-based blur preview
- Touch gesture controls (drag, rotate, pinch) for adjusting effect
- CameraX integration for camera preview and high-res capture
- EXIF metadata with GPS location support
- MediaStore integration for saving to gallery
- Jetpack Compose UI with haptic feedback

Tech stack: Kotlin, CameraX, OpenGL ES 2.0, Jetpack Compose
Min SDK: 26 (Android 8.0), Target SDK: 35 (Android 15)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Ole-Morten Duesund 2026-01-28 15:26:41 +01:00
commit 07e10ac9c3
38 changed files with 3489 additions and 0 deletions

88
README.md Normal file
View file

@ -0,0 +1,88 @@
# Tilt-Shift Camera
A dedicated Android camera app for tilt-shift photography with real-time preview, touch-based controls, and proper EXIF handling.
## Features
- **Real-time tilt-shift effect preview** - See the blur effect as you compose your shot
- **Touch-based controls**:
- Single finger drag to move the focus line position
- Two-finger rotation to adjust blur angle
- Pinch gesture to adjust blur zone size
- Pinch in center to zoom camera
- **Zoom controls** - Quick presets (0.5x, 1x, 2x, 5x) plus pinch-to-zoom
- **Auto picture orientation detection** - Photos saved with correct EXIF orientation
- **GPS location tagging** - Optional EXIF GPS data from device location
- **Haptic feedback** - Tactile response for all interactions
- **Saves to gallery** - Photos saved to Pictures/TiltShift/ folder
## Requirements
- Android 8.0 (API 26) or higher
- Device with camera
- OpenGL ES 2.0 support
## Building
1. Open the project in Android Studio
2. Sync Gradle files
3. Build and run on a physical device (camera preview won't work on emulator)
Or from command line:
```bash
./gradlew assembleDebug
```
## Permissions
- **Camera** (required) - For capturing photos
- **Location** (optional) - For GPS tagging in EXIF data
- **Vibrate** - For haptic feedback
## Architecture
The app uses:
- **CameraX** - Jetpack camera library for camera preview and capture
- **OpenGL ES 2.0** - Real-time shader-based blur effect
- **Jetpack Compose** - Modern declarative UI
- **Kotlin Coroutines & Flow** - Asynchronous operations and state management
### Project Structure
```
app/src/main/java/no/naiv/tiltshift/
├── MainActivity.kt # Entry point with permission handling
├── camera/
│ ├── CameraManager.kt # CameraX setup and control
│ ├── LensController.kt # Lens/zoom switching
│ └── ImageCaptureHandler.kt # Photo capture with effect
├── effect/
│ ├── TiltShiftRenderer.kt # OpenGL renderer
│ ├── TiltShiftShader.kt # GLSL shader management
│ └── BlurParameters.kt # Effect state
├── ui/
│ ├── CameraScreen.kt # Main Compose screen
│ ├── TiltShiftOverlay.kt # Touch gesture handling & visualization
│ ├── ZoomControl.kt # Zoom UI component
│ └── LensSwitcher.kt # Lens selection UI
├── storage/
│ ├── PhotoSaver.kt # MediaStore integration
│ └── ExifWriter.kt # EXIF metadata handling
└── util/
├── OrientationDetector.kt
├── LocationProvider.kt
└── HapticFeedback.kt
```
## How the Tilt-Shift Effect Works
The tilt-shift effect simulates a selective focus lens that makes scenes appear miniature. The app achieves this through:
1. **Camera Preview** → OpenGL SurfaceTexture
2. **Fragment Shader** calculates distance from the focus line for each pixel
3. **Gradient blur** is applied based on distance - center stays sharp, edges blur
4. **Two-pass Gaussian blur** (optimized as separable passes) for quality and performance
## License
MIT