Write the user's physical tilt into the saved photo's EXIF orientation

Capture saves the bitmap in the device's portrait frame (CameraX
rotates the sensor 90° to match the locked-portrait activity), so a
photo taken while the phone was held in landscape lands on disk as a
portrait-shaped bitmap with world-up pointing to the side. Tag the
EXIF orientation with the user's actual tilt at shutter time
(OrientationEventListener-derived deviceRotation, which up to now
was passed in but ignored), so gallery viewers rotate the photo to
match how the phone was held.

Bump to 1.1.15.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ole-Morten Duesund 2026-05-11 16:59:28 +02:00
commit b057613bac
2 changed files with 13 additions and 3 deletions

View file

@ -24,6 +24,7 @@ import kotlin.coroutines.resume
import kotlin.math.cos
import kotlin.math.sin
import kotlin.math.sqrt
import no.naiv.tiltshift.util.OrientationDetector
/**
* Handles capturing photos with the tilt-shift effect applied.
@ -121,10 +122,19 @@ class ImageCaptureHandler(
var thumbnail: Bitmap? = null
try {
thumbnail = createThumbnail(captureResult.processed)
// Camera bitmap is in the device's portrait frame (CameraX
// rotated the sensor 90° because the activity is locked to
// portrait). Tag the EXIF with the user's physical tilt
// when they pressed the shutter so viewers display the
// photo right-side-up regardless of how the phone was held.
val exifOrientation = OrientationDetector.degreesToExifOrientation(
OrientationDetector.rotationToDegrees(deviceRotation),
isFrontCamera
)
val result = photoSaver.saveBitmapPair(
original = captureResult.original,
processed = captureResult.processed,
orientation = ExifInterface.ORIENTATION_NORMAL,
orientation = exifOrientation,
location = location
)
if (result is SaveResult.Success) {