How to switch jetpack camerax preview from back to front vice versa? - android

When I try to switch the camera preview from BACK to FRONT my screen getting freeze and if I minimize the screen and restart the same then camera preview work perfectly.
below is the camera code.
private fun startCamera() {
CameraX.unbindAll()
val metrics = DisplayMetrics().also { viewFinder.display.getRealMetrics(it) }
val screenSize = Size(metrics.widthPixels, metrics.heightPixels)
val screenAspectRatio = Rational(metrics.widthPixels, metrics.heightPixels)
val previewConfig = PreviewConfig.Builder().apply {
setLensFacing(lensFacing)
setTargetResolution(screenSize)
setTargetAspectRatio(screenAspectRatio)
setTargetRotation(windowManager.defaultDisplay.rotation)
setTargetRotation(viewFinder.display.rotation)
}.build()
preview = Preview(previewConfig)
preview.setOnPreviewOutputUpdateListener {
viewFinder.surfaceTexture = it.surfaceTexture
updateTransform()
}
// Create configuration object for the image capture use case
val imageCaptureConfig = ImageCaptureConfig.Builder()
.apply {
setLensFacing(lensFacing)
setTargetAspectRatio(screenAspectRatio)
setTargetRotation(viewFinder.display.rotation)
setCaptureMode(ImageCapture.CaptureMode.MIN_LATENCY)
}.build()
// Build the image capture use case and attach button click listener
imageCapture = ImageCapture(imageCaptureConfig)
//for recording the video
val videoCaptureConfig = VideoCaptureConfig.Builder().apply {
setLensFacing(lensFacing)
setTargetAspectRatio(screenAspectRatio)
setTargetRotation(viewFinder.display.rotation)
}.build()
videoCapture = VideoCapture(videoCaptureConfig)
CameraX.bindToLifecycle(this, preview, imageCapture, videoCapture)
}
and the updateTransform code is
private fun updateTransform() {
val matrix = Matrix()
// Compute the center of the view finder
val centerX = viewFinder.width / 2f
val centerY = viewFinder.height / 2f
// Correct preview output to account for display rotation
val rotationDegrees = when (viewFinder.display.rotation) {
Surface.ROTATION_0 -> 0
Surface.ROTATION_90 -> 90
Surface.ROTATION_180 -> 180
Surface.ROTATION_270 -> 270
else -> return
}
matrix.postRotate(-rotationDegrees.toFloat(), centerX, centerY)
// Finally, apply transformations to our TextureView
viewFinder.setTransform(matrix)
}
I have try to switch between the camera preview is :
lensFacing = if (lensFacing == CameraX.LensFacing.BACK) {
CameraX.LensFacing.FRONT
} else
CameraX.LensFacing.BACK
try {
CameraX.getCameraWithLensFacing(lensFacing)
CameraX.unbind(preview, imageCapture, videoCapture)
startCamera()
} catch (e: Exception) {
e.printStackTrace()
}
and after calling the above code on button click preview getting freez.

You may need to again add textureView in onUpdated callback.
Refer this,
https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-master-dev/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java#168
Let me know if it works.

Related

All images taken with Android CameraX have incorrect orientation in their EXIF data

I am using CameraX https://developer.android.com/training/camerax to take some images. However, all my images come out the wrong rotation. They are all marked: ORIENTATION_ROTATE_90 Yes, I have checked to ensure that the orientation lock is not on and there is nothing in the manifest to lock the screen orientation nor am I overriding any orientation method.
No matter how I test it via simulator or real device, the orientation seems to be "locked". The only picture that turns out correctly rotated, is when the device is in portrait mode. However, it's still flagged as ORIENTATION_ROTATE_90
Can anyone see what I might be doing incorrectly?
private var imageCapture: ImageCapture? = null
private lateinit var cameraExecutor: ExecutorService
//.. other methods removed for brievity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Request camera permissions
cameraExecutor = Executors.newSingleThreadExecutor()
}
override fun onResume() {
super.onResume()
startCamera()
}
private fun startCamera() {
val cameraProviderFuture = ProcessCameraProvider.getInstance(requireContext())
cameraProviderFuture.addListener({
// Used to bind the lifecycle of cameras to the lifecycle owner
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
// Preview
val preview = Preview.Builder()
.build()
.also {
it.setSurfaceProvider(binding.cameraPreview.surfaceProvider)
}
imageCapture = Builder().build()
// Doesn't work
// activity?.display.let { d ->
// d.let { imageCapture!!.targetRotation = d!!.rotation }
// }
// Select back camera as a default
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
try {
// Unbind use cases before rebinding
cameraProvider.unbindAll()
// Bind use cases to camera
cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture)
} catch (exc: Exception) {
Log.e(TAG, "Use case binding failed", exc)
}
}, ContextCompat.getMainExecutor(requireContext()))
}
private fun captureImage() {
// Get a stable reference of the modifiable image capture use case
val imageCapture = imageCapture ?: return
// this way the images will stay in order
val id = System.currentTimeMillis().toString()
// Make directory if it doesn't exist, and build a file for the new image to go into
val photoFile = File("${sharedViewModel.fileDirectory}/${id}").apply {
#Suppress("RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
parentFile.mkdirs()
}
// Create output options object which contains file + metadata
val outputOptions = OutputFileOptions.Builder(photoFile).build()
// Set up image capture listener, which is triggered after photo has been taken
imageCapture.takePicture(
outputOptions, ContextCompat.getMainExecutor(requireContext()), object : OnImageSavedCallback {
override fun onError(exc: ImageCaptureException) {
Toast.makeText(requireContext(), "Photo capture failed: ${exc.message}", Toast.LENGTH_LONG).show()
Log.e(TAG, "Photo capture failed: ${exc.message}", exc)
}
override fun onImageSaved(output: OutputFileResults) {
fixRotation(photoFile.path)
}
})
}
private fun fixRotation(imageUri: String) {
val bitmap = File(imageUri)
if (!bitmap.exists()) return
Uri.parse(imageUri)?.let{
CoroutineScope(Dispatchers.IO).launch { spinAndSave(it) }
}
}
private suspend fun spinAndSave(imageURI: Uri) = withContext(Dispatchers.IO) {
val options = BitmapFactory.Options()
options.inPreferredConfig = Bitmap.Config.ARGB_8888
imageURI.path?.let { path ->
ExifInterface(path).getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED).let { orientation ->
debugOrientation(orientation)
val rotatedBitmap = rotateBitmap( BitmapFactory.decodeFile(path, options), orientation)!!
FileOutputStream(imageURI.path).use { fos ->
rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 50, fos)
Log.i(TAG,"New Image Saved")
}
}
}
}
private fun debugOrientation(orientation: Int) {
val o = when (orientation) {
ExifInterface.ORIENTATION_NORMAL -> "ORIENTATION_NORMAL"
ExifInterface.ORIENTATION_FLIP_HORIZONTAL -> "ORIENTATION_FLIP_HORIZONTAL"
ExifInterface.ORIENTATION_ROTATE_180 -> "ORIENTATION_ROTATE_180"
ExifInterface.ORIENTATION_FLIP_VERTICAL -> "ORIENTATION_FLIP_VERTICAL"
ExifInterface.ORIENTATION_TRANSPOSE -> "ORIENTATION_TRANSPOSE"
ExifInterface.ORIENTATION_ROTATE_90 -> "ORIENTATION_ROTATE_90"
ExifInterface.ORIENTATION_TRANSVERSE -> "ORIENTATION_TRANSVERSE"
ExifInterface.ORIENTATION_ROTATE_270 -> "ORIENTATION_ROTATE_270"
else -> "UKNONWN ORIENTATION"
}
Log.w(TAG,"ORIEntation int: $orientation is: $o")
}
private fun rotateBitmap(bitmap: Bitmap, orientation: Int): Bitmap? {
val matrix = Matrix()
when (orientation) {
ExifInterface.ORIENTATION_NORMAL -> return bitmap
ExifInterface.ORIENTATION_FLIP_HORIZONTAL -> matrix.setScale(-1f, 1f)
ExifInterface.ORIENTATION_ROTATE_180 -> matrix.setRotate(180f)
ExifInterface.ORIENTATION_FLIP_VERTICAL -> {
matrix.setRotate(180f)
matrix.postScale(-1f, 1f)
}
ExifInterface.ORIENTATION_TRANSPOSE -> {
matrix.setRotate(90f)
matrix.postScale(-1f, 1f)
}
ExifInterface.ORIENTATION_ROTATE_90 -> matrix.setRotate(90f)
ExifInterface.ORIENTATION_TRANSVERSE -> {
matrix.setRotate(-90f)
matrix.postScale(-1f, 1f)
}
ExifInterface.ORIENTATION_ROTATE_270 -> matrix.setRotate(-90f)
else -> return bitmap
}
return try {
val bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
bitmap.recycle()
bmRotated
} catch (e: OutOfMemoryError) {
e.printStackTrace()
null
}
}
use below of code to get exif and rotate of image file. Bitmap don't have exif.
public static Bitmap rotateImage(String path) throws IOException {
Bitmap bitmap = BitmapFactory.decodeFile(path);
int rotate = 0;
ExifInterface exif;
exif = new ExifInterface(path);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
Matrix matrix = new Matrix();
matrix.postRotate(rotate);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), matrix, true);
}

Preview is stretched on CameraX PreviewView

i am exciting to use CameraX on my app.,
my reference from google officialy CameraX on github,
but something wrong., please help me.,
this my code to set aspect ratio
private fun aspectRatio(width: Int, height: Int): Int {
val previewRatio = max(width, height).toDouble() / min(width, height)
if (abs(previewRatio - RATIO_4_3_VALUE) <= abs(previewRatio - RATIO_16_9_VALUE)) {
return AspectRatio.RATIO_4_3
}
return AspectRatio.RATIO_16_9
}
And this my preview code
#SuppressLint("UnsafeExperimentalUsageError")private fun startCamera() {
val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
viewFinder=binding.surfaceView
cameraProviderFuture.addListener({
// Used to bind the lifecycle of cameras to the lifecycle owner
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
val metrics = DisplayMetrics().also { viewFinder.display.getRealMetrics(it) }
Log.d(TAG, "Screen metrics: ${metrics.widthPixels} x ${metrics.heightPixels}")
val screenAspectRatio = aspectRatio(metrics.widthPixels, metrics.heightPixels)
Log.d(TAG, "Preview aspect ratio: $screenAspectRatio")
Size(metrics.widthPixels, metrics.heightPixels)
val rotation = viewFinder.display.rotation
// Preview
val preview = Preview.Builder()
.setTargetRotation(rotation)
.setTargetAspectRatio(screenAspectRatio)
.build()
imageCapture = if (flashStatus) {
ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
.setTargetRotation(rotationimage)
.setTargetAspectRatio(screenAspectRatio)
.build()
} else {
ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
.setTargetRotation(rotationimage)
.build()
}
// Select back camera as a default
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
// Unbind use cases before rebinding
cameraProvider.unbindAll()
viewFinder.scaleType=PreviewView.ScaleType.FILL_CENTER
try {
// Bind use cases to camera
val cam = cameraProvider.bindToLifecycle(
this, cameraSelector, preview, imageCapture)
if (!flashStatus) {
if (cam.cameraInfo.hasFlashUnit()) {
cam.cameraControl.enableTorch(true)
}
} else {
cam.cameraControl.enableTorch(false)
}
// Attach the viewfinder's surface provider to preview use case
preview.setSurfaceProvider(viewFinder.surfaceProvider)
} catch (exc: Exception) {
Log.e(TAG, "Use case binding failed", exc)
}
}, ContextCompat.getMainExecutor(this))
}
and this output preview
output preview is stretched
what is wrong on my code?
thank you for your help me folks.,
UPDATE
when my device on dark mode, the preview is normal.
preview normal on dark mode
how to fixed in normal mode??

Android CameraX - Camera preview freezes on first call to captureUseCase.takePicture()

I am using android camera X api to capture selfie image by analyzing the face detected.
The app captures more than 5 images if the face is inside rectangular frame show on the screen.
The issue is, camera preview freezes(few seconds) when capturing image for the first time.
I am using the below code to set up camera provider in my activity.
// preview use case
internal fun bindPreviewUseCase(previewView: PreviewView) {
Util.printDebugLog("Binding camera preview use case.")
if (previewUseCase != null) {
cameraProvider.unbind(previewUseCase)
}
previewUseCase = Preview.Builder()
.setTargetResolution(Size(480, 800))
.build()
previewUseCase!!.setSurfaceProvider(previewView.createSurfaceProvider())
cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, previewUseCase)
}
// analysis use case
internal fun bindAnalysisUseCase(graphicOverlay: GraphicOverlay) {
Util.printDebugLog("Binding camera analysis use case.")
if (analysisUseCase != null) {
cameraProvider.unbind(analysisUseCase)
}
imageProcessor?.stop()
try {
val faceDetectorOptions: FaceDetectorOptions = getFaceDetectorOptionsForLivePreview()
imageProcessor =
LiveFaceDetectorProcessor(context, faceDetectorOptions, faceFrameProcessListener)
} catch (e: Exception) {
Viola.listener.onFaceDetectionFailed(
FaceDetectionError.IMAGE_PROCESSOR_ERROR,
"Can not create image processor: ${e.localizedMessage}"
)
return
}
val builder = ImageAnalysis.Builder()
builder.setTargetResolution(Size(480, 800))
analysisUseCase = builder.build()
needUpdateGraphicOverlayImageSourceInfo = true
analysisUseCase!!.setAnalyzer(
ContextCompat.getMainExecutor(context),
ImageAnalysis.Analyzer { imageProxy: ImageProxy ->
if (needUpdateGraphicOverlayImageSourceInfo) {
val isImageFlipped =
lensFacing == CameraSelector.LENS_FACING_FRONT
val rotationDegrees = imageProxy.imageInfo.rotationDegrees
if (rotationDegrees == 0 || rotationDegrees == 180) {
graphicOverlay.setImageSourceInfo(
imageProxy.width, imageProxy.height, isImageFlipped
)
} else {
graphicOverlay.setImageSourceInfo(
imageProxy.height, imageProxy.width, isImageFlipped
)
}
needUpdateGraphicOverlayImageSourceInfo = false
}
try {
imageProcessor!!.processImageProxy(imageProxy, graphicOverlay)
} catch (e: MlKitException) {
Viola.listener.onFaceDetectionFailed(
FaceDetectionError.IMAGE_PROCESSOR_ERROR,
"Failed to process image: ${e.localizedMessage}"
)
}
}
)
cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, analysisUseCase)
}
// capture use case
internal fun bindCaptureUseCase(previewView: PreviewView) {
Util.printDebugLog("Binding camera capture use case.")
if (captureUseCase != null) {
cameraProvider.unbind(captureUseCase)
}
val rotation = previewView.display.rotation
captureUseCase = ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.setTargetResolution(Size(960, 1280))
.setTargetRotation(rotation)
.build()
cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, captureUseCase)
}
//capture
internal fun takePicture(callback: CaptureCallback) {
Util.printDebugLog("Capturing current frame.")
val diff = System.currentTimeMillis() - lastCaptureTime
if (diff > captureDelay) {
if (!isCaptureInProgress) {
if (captureUseCase == null) {
return
}
isCaptureInProgress = true
lastCaptureTime = System.currentTimeMillis()
val executor = ContextCompat.getMainExecutor(context)
//TODO remove
val startTime = System.currentTimeMillis()
captureUseCase!!.takePicture(
executor,
object : ImageCapture.OnImageCapturedCallback() {
override fun onCaptureSuccess(image: ImageProxy) {
val timeElapsed = System.currentTimeMillis() - startTime
Util.printDebugLog("Image captured, producing bitmap from image proxy. $timeElapsed")
val bitmap: Bitmap =
BitmapUtil.getBitmap(image, image.imageInfo.rotationDegrees)!!
image.close()
callback.onCaptured(bitmap)
isCaptureInProgress = false
super.onCaptureSuccess(image)
}
override fun onError(exception: ImageCaptureException) {
super.onError(exception)
isCaptureInProgress = false
Util.printDebugLog("Unable to capture: ${exception.localizedMessage}")
}
})
}
} else {
Util.printDebugLog("Capture called before minimum delay.Ignoring capture call.")
}
}
// dependencies used
implementation "androidx.camera:camera-camera2:1.0.0-beta07"
implementation "androidx.camera:camera-view:1.0.0-alpha14"
implementation "androidx.camera:camera-lifecycle:1.0.0-beta07"
// time taken for each capture(in milliseconds)
image 1 -> 2396
image 2 -> 411
image 3 -> 356
image 4 -> 386
image 5 -> 345

ImageCapture doesn't care about zoomRatio on Camera

I'm willing to implement zoom feature in my app with CameraX API. I followed this medium post to implement pinch to zoom and it works.
The problem is when I retrieve the captured image in onCaptureSuccess callback, The image is not zoomed.
Here is the code I use to implement zoom on Camera in onCreate():
//ZOOM
val listener = object : ScaleGestureDetector.SimpleOnScaleGestureListener() {
override fun onScale(detector: ScaleGestureDetector): Boolean {
val zoomRatio = camera?.cameraInfo?.zoomState?.value?.zoomRatio ?: 0f
val scale = zoomRatio * detector.scaleFactor
camera?.cameraControl?.setZoomRatio(scale)
return true
}
}
scaleDetector = ScaleGestureDetector(context, listener)
And in method "bindCameraUseCases()" :
previewCamera.setOnTouchListener { _, event ->
scaleDetector.onTouchEvent(event)
}
The full method if needed :
/** Declare and bind preview, capture and analysis use cases */
fun bindCameraUseCases() {
// Get screen metrics used to setup camera for full screen resolution
val metrics = DisplayMetrics().also { previewCamera.display.getRealMetrics(it) }
Log.d(TAG, "Screen metrics: ${metrics.widthPixels} x ${metrics.heightPixels}")
val rotation = previewCamera.display.rotation
// Bind the CameraProvider to the LifeCycleOwner
val cameraSelector = CameraSelector.Builder().requireLensFacing(lensFacing).build()
val cameraProviderFuture = ProcessCameraProvider.getInstance(requireContext())
cameraProviderFuture.addListener(Runnable {
// CameraProvider
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
// Preview
preview = Preview.Builder()
.setTargetRotation(rotation)
.build()
previewCamera.preferredImplementationMode =
PreviewView.ImplementationMode.TEXTURE_VIEW // when setting to TEXTURE_VIEW, preview doesnt take full screen on back pressed
previewCamera.setOnTouchListener { _, event ->
scaleDetector.onTouchEvent(event)
}
// Default PreviewSurfaceProvider
preview?.setSurfaceProvider(previewCamera.createSurfaceProvider(camera?.cameraInfo))
val screenAspectRatio = aspectRatio(metrics.widthPixels, metrics.heightPixels)
// ImageCapture
imageCapture = ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.setTargetAspectRatio(screenAspectRatio)
.setTargetRotation(rotation)
.build()
// ImageAnalysis
imageAnalyzer = ImageAnalysis.Builder()
.setTargetAspectRatio(screenAspectRatio)
.setTargetRotation(rotation)
.build()
cameraProvider.unbindAll()
try {
camera = cameraProvider.bindToLifecycle(
this as LifecycleOwner, cameraSelector, preview, imageCapture, imageAnalyzer
)
} catch (exc: Exception) {
Log.e(TAG, "Use case binding failed", exc)
}
}, mainExecutor)
}
As I mentionned, zoom is working but then in onCaptureSucess, ImageProxy is not zoomed.
override fun onCaptureSuccess(image: ImageProxy) {
image.use { image ->
savedBitmap = image.imageProxyToBitmap()
///...
}
}
Here is the extension function to retrieve bitmap from imageProxy :
fun ImageProxy.imageProxyToBitmap(): Bitmap {
val buffer = this.planes[0].buffer
buffer.rewind()
val bytes = ByteArray(buffer.capacity())
buffer.get(bytes)
val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
val matrix = Matrix()
matrix.postRotate(90f)
return Bitmap.createBitmap(bitmap, 0, 0,bitmap.width,bitmap.height, matrix, true)
}
Here are my dependencies :
// CameraX core library
def camerax_version = "1.0.0-beta02"
implementation "androidx.camera:camera-core:$camerax_version"
// CameraX Camera2 extensions
implementation "androidx.camera:camera-camera2:$camerax_version"
// CameraX Lifecycle library
implementation "androidx.camera:camera-lifecycle:$camerax_version"
// CameraX View class
implementation "androidx.camera:camera-view:1.0.0-alpha09"
Thank you for your help 🙏
not sure why this happens but we are unable to reproduce the issue.
In my test, ImageCapture always captures the image with zoom applied.
Currently I suspect this could a device issue. It could be helpful if you can provide the device name. It will also be helpful if you can verify it on other devices.

How to prevent CameraX from turning while

I build an app using CameraX codelab example, that is orking fine, but once my mobile gone into sleep and screen turned off, the CameraX transmittion had not been resumed after returning the mobile to normal status, and the CameraX screen remain white?
UPDATE
Sorry, it is not the Camera itself, The camera is invisible, and I've an image view, for which the image analyzer is displaying what is seen in the camera.
It look the val bitmap = view_finder.bitmap ?: return#Analyzer is returning null in my code below once the mobile goes in sleep.
private lateinit var viewFinder: TextureView
private fun startCamera() {
val previewConfig = PreviewConfig.Builder().apply {
setTargetAspectRatio(Rational(1, 1))
setTargetResolution(Size(640, 640))
}.build()
val preview = Preview(previewConfig)
preview.setOnPreviewOutputUpdateListener {
val parent = viewFinder.parent as ViewGroup
parent.removeView(viewFinder)
parent.addView(viewFinder, 0)
viewFinder.surfaceTexture = it.surfaceTexture
updateTransform()
}
val imageCaptureConfig = Builder()
.apply {
setTargetAspectRatio(Rational(1, 1))
setCaptureMode(ImageCapture.CaptureMode.MIN_LATENCY)
}.build()
val imageCapture = ImageCapture(imageCaptureConfig)
findViewById<ImageButton>(R.id.capture_button).setOnClickListener {
val file = File(externalMediaDirs.first(),
"${System.currentTimeMillis()}.jpg")
imageCapture.takePicture(file,
object : ImageCapture.OnImageSavedListener {
override fun onError(error: ImageCapture.UseCaseError,
message: String, exc: Throwable?) {
val msg = "Photo capture failed: $message"
Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
Log.e("CameraXApp", msg)
exc?.printStackTrace()
}
override fun onImageSaved(file: File) {
val msg = "Photo capture succeeded: ${file.absolutePath}"
Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
Log.d("CameraXApp", msg)
}
})
}
// Setup image analysis pipeline that computes average pixel luminance
val analyzerConfig = ImageAnalysisConfig.Builder().apply {
val analyzerThread = HandlerThread(
"LuminosityAnalysis").apply { start() }
setCallbackHandler(Handler(analyzerThread.looper))
setImageReaderMode(
ImageAnalysis.ImageReaderMode.ACQUIRE_LATEST_IMAGE)
}.build()
val analyzerUseCase = ImageAnalysis(analyzerConfig).apply {
////// This is my own code that I added to the analyzer ///////
analyzer = ImageAnalysis.Analyzer { image, rotationDegrees ->
val bitmap = view_finder.bitmap ?: return#Analyzer
scope.launch(Dispatchers.Unconfined) {
val mat = Mat()
Utils.bitmapToMat(bitmap!!, mat)
val detectedFaces = FaceDetection.detectFaces(bitmap!!)
println("Detected Faces = $detectedFaces")
Toast.makeText(
this#MainActivity, "Detected Faces = ${detectedFaces.toArray().size}",
Toast.LENGTH_SHORT
).show()
if (detectedFaces.toArray().isNotEmpty()) {
val paint = Paint().apply {
isAntiAlias = true
style = Paint.Style.STROKE
color = Color.RED
strokeWidth = 10f
}
for (rect in detectedFaces.toArray()) {
bitmap?.let { Canvas(it) }?.apply {
drawRect(
rect.x.toFloat(), // faceRectangle.left,
rect.y.toFloat(), //faceRectangle.top,
rect.x.toFloat() + rect.width,
rect.y.toFloat() + rect.height,
paint
)
}
}
}
}
runOnUiThread { imageView.setImageBitmap(bitmap) }
}
}
CameraX.bindToLifecycle(
this, preview, imageCapture, analyzerUseCase)
}
I also had the same issue and this solution worked for me.
We can add the following line of code in onCreate(), to keep the device awake
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
Here is the reference link from docs
https://developer.android.com/training/scheduling/wakelock

Categories

Resources