mirror of
https://github.com/SimpleMobileTools/Simple-Camera.git
synced 2025-02-17 03:40:38 +01:00
improving the Touch To Focus functionality
This commit is contained in:
parent
94488adb24
commit
67b3b50fa8
@ -0,0 +1,5 @@
|
|||||||
|
package com.simplemobiletools.camera.models
|
||||||
|
|
||||||
|
import android.graphics.Rect
|
||||||
|
|
||||||
|
data class FocusArea(val rect: Rect, val weight: Int)
|
@ -3,9 +3,7 @@ package com.simplemobiletools.camera.views
|
|||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.annotation.TargetApi
|
import android.annotation.TargetApi
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.ImageFormat
|
import android.graphics.*
|
||||||
import android.graphics.Point
|
|
||||||
import android.graphics.SurfaceTexture
|
|
||||||
import android.hardware.camera2.*
|
import android.hardware.camera2.*
|
||||||
import android.hardware.camera2.params.MeteringRectangle
|
import android.hardware.camera2.params.MeteringRectangle
|
||||||
import android.media.ImageReader
|
import android.media.ImageReader
|
||||||
@ -21,6 +19,7 @@ import android.view.ViewGroup
|
|||||||
import com.simplemobiletools.camera.activities.MainActivity
|
import com.simplemobiletools.camera.activities.MainActivity
|
||||||
import com.simplemobiletools.camera.helpers.*
|
import com.simplemobiletools.camera.helpers.*
|
||||||
import com.simplemobiletools.camera.interfaces.MyPreview
|
import com.simplemobiletools.camera.interfaces.MyPreview
|
||||||
|
import com.simplemobiletools.camera.models.FocusArea
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.Semaphore
|
import java.util.concurrent.Semaphore
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
@ -57,6 +56,8 @@ class PreviewCameraTwo : ViewGroup, TextureView.SurfaceTextureListener, MyPrevie
|
|||||||
private var mCaptureSession: CameraCaptureSession? = null
|
private var mCaptureSession: CameraCaptureSession? = null
|
||||||
private var mPreviewRequestBuilder: CaptureRequest.Builder? = null
|
private var mPreviewRequestBuilder: CaptureRequest.Builder? = null
|
||||||
private var mPreviewRequest: CaptureRequest? = null
|
private var mPreviewRequest: CaptureRequest? = null
|
||||||
|
private val mCameraToPreviewMatrix = Matrix()
|
||||||
|
private val mPreviewToCameraMatrix = Matrix()
|
||||||
private val mCameraOpenCloseLock = Semaphore(1)
|
private val mCameraOpenCloseLock = Semaphore(1)
|
||||||
|
|
||||||
constructor(context: Context) : super(context)
|
constructor(context: Context) : super(context)
|
||||||
@ -379,9 +380,6 @@ class PreviewCameraTwo : ViewGroup, TextureView.SurfaceTextureListener, MyPrevie
|
|||||||
private fun focusArea() {
|
private fun focusArea() {
|
||||||
mActivity.drawFocusCircle(mLastClickX, mLastClickY)
|
mActivity.drawFocusCircle(mLastClickX, mLastClickY)
|
||||||
|
|
||||||
val characteristics = getCameraManager().getCameraCharacteristics(mCameraId)
|
|
||||||
val sensorArraySize = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE)
|
|
||||||
|
|
||||||
val captureCallbackHandler = object : CameraCaptureSession.CaptureCallback() {
|
val captureCallbackHandler = object : CameraCaptureSession.CaptureCallback() {
|
||||||
override fun onCaptureCompleted(session: CameraCaptureSession, request: CaptureRequest, result: TotalCaptureResult) {
|
override fun onCaptureCompleted(session: CameraCaptureSession, request: CaptureRequest, result: TotalCaptureResult) {
|
||||||
super.onCaptureCompleted(session, request, result)
|
super.onCaptureCompleted(session, request, result)
|
||||||
@ -399,18 +397,14 @@ class PreviewCameraTwo : ViewGroup, TextureView.SurfaceTextureListener, MyPrevie
|
|||||||
set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF)
|
set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF)
|
||||||
mCaptureSession!!.capture(build(), captureCallbackHandler, mBackgroundHandler)
|
mCaptureSession!!.capture(build(), captureCallbackHandler, mBackgroundHandler)
|
||||||
|
|
||||||
if (characteristics.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AF) >= 1) {
|
val characteristics = getCameraManager().getCameraCharacteristics(mCameraId)
|
||||||
val x = (mLastClickX / mTextureView.width) * sensorArraySize.height()
|
|
||||||
val y = (mLastClickY / mTextureView.height) * sensorArraySize.width()
|
|
||||||
val halfTouchWidth = 150
|
|
||||||
val halfTouchHeight = 150
|
|
||||||
val focusAreaTouch = MeteringRectangle(Math.max(x - halfTouchWidth, 0f).toInt(),
|
|
||||||
Math.max(y - halfTouchHeight, 0f).toInt(),
|
|
||||||
halfTouchWidth * 2,
|
|
||||||
halfTouchHeight * 2,
|
|
||||||
MeteringRectangle.METERING_WEIGHT_MAX - 1)
|
|
||||||
|
|
||||||
set(CaptureRequest.CONTROL_AF_REGIONS, arrayOf(focusAreaTouch))
|
// touch-to-focus inspired by OpenCamera
|
||||||
|
if (characteristics.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AF) >= 1) {
|
||||||
|
val focusArea = getFocusArea()
|
||||||
|
val sensorRect = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE)
|
||||||
|
val meteringRect = convertAreaToMeteringRectangle(sensorRect, focusArea)
|
||||||
|
set(CaptureRequest.CONTROL_AF_REGIONS, arrayOf(meteringRect))
|
||||||
}
|
}
|
||||||
|
|
||||||
set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO)
|
set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO)
|
||||||
@ -421,6 +415,77 @@ class PreviewCameraTwo : ViewGroup, TextureView.SurfaceTextureListener, MyPrevie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun convertAreaToMeteringRectangle(sensorRect: Rect, focusArea: FocusArea): MeteringRectangle {
|
||||||
|
val camera2Rect = convertRectToCamera2(sensorRect, focusArea.rect)
|
||||||
|
return MeteringRectangle(camera2Rect, focusArea.weight)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun convertRectToCamera2(cropRect: Rect, rect: Rect): Rect {
|
||||||
|
val leftF = (rect.left + 1000) / 2000.0
|
||||||
|
val topF = (rect.top + 1000) / 2000.0
|
||||||
|
val rightF = (rect.right + 1000) / 2000.0
|
||||||
|
val bottomF = (rect.bottom + 1000) / 2000.0
|
||||||
|
var left = (cropRect.left + leftF * (cropRect.width() - 1)).toInt()
|
||||||
|
var right = (cropRect.left + rightF * (cropRect.width() - 1)).toInt()
|
||||||
|
var top = (cropRect.top + topF * (cropRect.height() - 1)).toInt()
|
||||||
|
var bottom = (cropRect.top + bottomF * (cropRect.height() - 1)).toInt()
|
||||||
|
left = Math.max(left, cropRect.left)
|
||||||
|
right = Math.max(right, cropRect.left)
|
||||||
|
top = Math.max(top, cropRect.top)
|
||||||
|
bottom = Math.max(bottom, cropRect.top)
|
||||||
|
left = Math.min(left, cropRect.right)
|
||||||
|
right = Math.min(right, cropRect.right)
|
||||||
|
top = Math.min(top, cropRect.bottom)
|
||||||
|
bottom = Math.min(bottom, cropRect.bottom)
|
||||||
|
|
||||||
|
return Rect(left, top, right, bottom)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getFocusArea(): FocusArea {
|
||||||
|
val coords = floatArrayOf(mLastClickX, mLastClickY)
|
||||||
|
calculateCameraToPreviewMatrix()
|
||||||
|
mPreviewToCameraMatrix.mapPoints(coords)
|
||||||
|
val focusX = coords[0].toInt()
|
||||||
|
val focusY = coords[1].toInt()
|
||||||
|
|
||||||
|
val focusSize = 50
|
||||||
|
val rect = Rect()
|
||||||
|
rect.left = focusX - focusSize
|
||||||
|
rect.right = focusX + focusSize
|
||||||
|
rect.top = focusY - focusSize
|
||||||
|
rect.bottom = focusY + focusSize
|
||||||
|
|
||||||
|
if (rect.left < -1000) {
|
||||||
|
rect.left = -1000
|
||||||
|
rect.right = rect.left + 2 * focusSize
|
||||||
|
} else if (rect.right > 1000) {
|
||||||
|
rect.right = 1000
|
||||||
|
rect.left = rect.right - 2 * focusSize
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rect.top < -1000) {
|
||||||
|
rect.top = -1000
|
||||||
|
rect.bottom = rect.top + 2 * focusSize
|
||||||
|
} else if (rect.bottom > 1000) {
|
||||||
|
rect.bottom = 1000
|
||||||
|
rect.top = rect.bottom - 2 * focusSize
|
||||||
|
}
|
||||||
|
|
||||||
|
return FocusArea(rect, MeteringRectangle.METERING_WEIGHT_MAX)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun calculateCameraToPreviewMatrix() {
|
||||||
|
val yScale = if (getIsUsingFrontCamera()) -1 else 1
|
||||||
|
mCameraToPreviewMatrix.apply {
|
||||||
|
reset()
|
||||||
|
setScale(1f, yScale.toFloat())
|
||||||
|
postRotate(mSensorOrientation.toFloat())
|
||||||
|
postScale(mTextureView.width / 2000f, mTextureView.height / 2000f)
|
||||||
|
postTranslate(mTextureView.width / 2f, mTextureView.height / 2f)
|
||||||
|
invert(mPreviewToCameraMatrix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun lockFocus() {
|
private fun lockFocus() {
|
||||||
try {
|
try {
|
||||||
mPreviewRequestBuilder!!.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START)
|
mPreviewRequestBuilder!!.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user