fix #17, improve photo saving rotation

This commit is contained in:
tibbi 2017-03-25 17:59:25 +01:00
parent 5e9e1798c5
commit 726ab0acd2
6 changed files with 46 additions and 24 deletions

View File

@ -32,7 +32,7 @@ android {
}
dependencies {
compile 'com.simplemobiletools:commons:2.13.9'
compile 'com.simplemobiletools:commons:2.14.6'
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}

View File

@ -1,12 +1,18 @@
package com.simplemobiletools.camera
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Matrix
import android.media.ExifInterface
import android.net.Uri
import android.os.AsyncTask
import android.os.Environment
import android.util.Log
import com.simplemobiletools.camera.Preview.Companion.config
import com.simplemobiletools.camera.activities.MainActivity
import com.simplemobiletools.camera.extensions.compensateDeviceRotation
import com.simplemobiletools.camera.extensions.getOutputMediaFile
import com.simplemobiletools.camera.extensions.getPreviewRotation
import com.simplemobiletools.commons.extensions.getFileDocument
import com.simplemobiletools.commons.extensions.needsStupidWritePermissions
import com.simplemobiletools.commons.extensions.toast
@ -16,7 +22,7 @@ import java.io.IOException
import java.io.OutputStream
import java.lang.ref.WeakReference
class PhotoProcessor(val activity: MainActivity, val uri: Uri?) : AsyncTask<ByteArray, Void, String>() {
class PhotoProcessor(val activity: MainActivity, val uri: Uri?, val currCameraId: Int) : AsyncTask<ByteArray, Void, String>() {
companion object {
private val TAG = PhotoProcessor::class.java.simpleName
private var mActivity: WeakReference<MainActivity>? = null
@ -40,6 +46,7 @@ class PhotoProcessor(val activity: MainActivity, val uri: Uri?) : AsyncTask<Byte
return ""
}
val data = params[0]
val photoFile = File(path)
if (activity.needsStupidWritePermissions(path)) {
if (config.treeUri.isEmpty()) {
@ -56,8 +63,20 @@ class PhotoProcessor(val activity: MainActivity, val uri: Uri?) : AsyncTask<Byte
fos = FileOutputStream(photoFile)
}
val data = params[0]
fos?.write(data)
var image = BitmapFactory.decodeByteArray(data, 0, data.size)
val exif = ExifInterface(photoFile.toString())
val deviceRot = MainActivity.mOrientation.compensateDeviceRotation(currCameraId)
val previewRot = activity.getPreviewRotation(currCameraId)
val imageRot = when (exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED)) {
ExifInterface.ORIENTATION_ROTATE_90 -> 90
ExifInterface.ORIENTATION_ROTATE_180 -> 180
ExifInterface.ORIENTATION_ROTATE_270 -> 270
else -> 0
}
image = rotate(image, imageRot + deviceRot + previewRot)
image.compress(Bitmap.CompressFormat.JPEG, 80, fos)
fos?.close()
return photoFile.absolutePath
} catch (e: Exception) {
@ -73,8 +92,18 @@ class PhotoProcessor(val activity: MainActivity, val uri: Uri?) : AsyncTask<Byte
return ""
}
fun rotate(bitmap: Bitmap, degree: Int): Bitmap {
val width = bitmap.width
val height = bitmap.height
val matrix = Matrix()
matrix.setRotate(degree.toFloat())
return Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true)
}
override fun onPostExecute(path: String) {
super.onPostExecute(path)
mActivity?.get()?.mediaSaved(path)
}

View File

@ -252,12 +252,8 @@ class Preview : ViewGroup, SurfaceHolder.Callback, MediaScannerConnection.OnScan
fun takePicture() {
if (mCanTakePicture) {
var rotation = mActivity.getMediaRotation(mCurrCameraId)
rotation += mCallback.getCurrentOrientation().compensateDeviceRotation(mCurrCameraId)
val selectedResolution = getSelectedResolution()
mParameters!!.setPictureSize(selectedResolution.width, selectedResolution.height);
mParameters!!.setRotation(rotation % 360)
if (config.isSoundEnabled) {
val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
@ -287,7 +283,7 @@ class Preview : ViewGroup, SurfaceHolder.Callback, MediaScannerConnection.OnScan
resumePreview()
}
PhotoProcessor(mActivity, mTargetUri).execute(data)
PhotoProcessor(mActivity, mTargetUri, mCurrCameraId).execute(data)
}
private fun resumePreview() {
@ -534,13 +530,12 @@ class Preview : ViewGroup, SurfaceHolder.Callback, MediaScannerConnection.OnScan
} catch (e: Exception) {
setupFailed(e)
}
} else {
mRecorder!!.setOutputFile(mCurrVideoPath)
}
mRecorder!!.setPreviewDisplay(mSurfaceHolder.surface)
val rotation = mActivity.getFinalRotation(mCurrCameraId, mCallback.getCurrentOrientation())
val rotation = mActivity.getMediaRotation(mCurrCameraId)
mInitVideoRotation = rotation
mRecorder!!.setOrientationHint(rotation)
@ -571,7 +566,7 @@ class Preview : ViewGroup, SurfaceHolder.Callback, MediaScannerConnection.OnScan
}
private fun startRecording() {
if (mInitVideoRotation != mActivity.getFinalRotation(mCurrCameraId, mCallback.getCurrentOrientation())) {
if (mInitVideoRotation != mActivity.getFinalRotation(mCurrCameraId, MainActivity.mOrientation)) {
cleanupRecorder()
initRecorder()
}
@ -659,8 +654,6 @@ class Preview : ViewGroup, SurfaceHolder.Callback, MediaScannerConnection.OnScan
fun setIsCameraAvailable(available: Boolean)
fun getCurrentOrientation(): Int
fun videoSaved(uri: Uri)
fun drawFocusRect(x: Int, y: Int)

View File

@ -52,9 +52,9 @@ class MainActivity : SimpleActivity(), SensorEventListener, PreviewListener, Pho
private var mIsVideoCaptureIntent = false
private var mIsHardwareShutterHandled = false
private var mCurrVideoRecTimer = 0
private var mOrientation = 0
private var mCurrCameraId = 0
private var mLastHandledOrientation = 0
var mOrientation = 0
}
override fun onCreate(savedInstanceState: Bundle?) {
@ -531,8 +531,6 @@ class MainActivity : SimpleActivity(), SensorEventListener, PreviewListener, Pho
mIsCameraAvailable = available
}
override fun getCurrentOrientation() = mOrientation
override fun videoSaved(uri: Uri) {
setupPreviewImage(mIsInPhotoMode)
if (mIsVideoCaptureIntent) {

View File

@ -6,7 +6,7 @@ import android.view.Surface
fun Activity.getPreviewRotation(cameraId: Int): Int {
val info = getCameraInfo(cameraId)
val degrees = getRotationDegrees(this)
val degrees = getDeviceRotationDegrees()
var result: Int
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
@ -20,7 +20,7 @@ fun Activity.getPreviewRotation(cameraId: Int): Int {
}
fun Activity.getMediaRotation(cameraId: Int): Int {
val degrees = getRotationDegrees(this)
val degrees = getDeviceRotationDegrees()
val info = getCameraInfo(cameraId)
return if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
(360 + info.orientation + degrees) % 360
@ -30,11 +30,10 @@ fun Activity.getMediaRotation(cameraId: Int): Int {
fun Activity.getFinalRotation(currCameraId: Int, deviceOrientation: Int): Int {
var rotation = getMediaRotation(currCameraId)
rotation += deviceOrientation.compensateDeviceRotation(currCameraId)
return rotation % 360
}
private fun getRotationDegrees(activity: Activity) = when (activity.windowManager.defaultDisplay.rotation) {
fun Activity.getDeviceRotationDegrees() = when (windowManager.defaultDisplay.rotation) {
Surface.ROTATION_90 -> 90
Surface.ROTATION_180 -> 180
Surface.ROTATION_270 -> 270

View File

@ -7,9 +7,12 @@ import com.simplemobiletools.camera.ORIENT_LANDSCAPE_RIGHT
fun Int.compensateDeviceRotation(currCameraId: Int): Int {
val isFrontCamera = currCameraId == Camera.CameraInfo.CAMERA_FACING_FRONT
return if (this == ORIENT_LANDSCAPE_LEFT) {
if (isFrontCamera) 90 else 270
270
} else if (this == ORIENT_LANDSCAPE_RIGHT) {
if (isFrontCamera) 270 else 90
} else
90
} else if (isFrontCamera) {
180
} else {
0
}
}