No description
- Kotlin 96.4%
- GLSL 2.9%
- Shell 0.7%
State persistence: - Use rememberUpdatedState to always get latest params inside pointerInput - Capture gestureStartParams at beginning of each gesture - All adjustments now use initial values + accumulated change Drag tracking: - Track initialDragCentroid at drag start - Calculate total drag offset from initial point (not frame-by-frame) - Drag now properly moves focus center 1:1 Shader rotation sync: - Adjust angle by -90° in shader to compensate for portrait texture rotation - Preview blur effect now rotates in sync with overlay UI Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> |
||
|---|---|---|
| app | ||
| gradle | ||
| .gitignore | ||
| build.gradle.kts | ||
| gradle.properties | ||
| gradlew | ||
| gradlew.bat | ||
| README.md | ||
| settings.gradle.kts | ||
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
- Open the project in Android Studio
- Sync Gradle files
- Build and run on a physical device (camera preview won't work on emulator)
Or from command line:
./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:
- Camera Preview → OpenGL SurfaceTexture
- Fragment Shader calculates distance from the focus line for each pixel
- Gradient blur is applied based on distance - center stays sharp, edges blur
- Two-pass Gaussian blur (optimized as separable passes) for quality and performance
License
MIT