/// <summary> /// https://codelabs.developers.google.com/codelabs/camerax-getting-started#3 /// </summary> private void StartCamera() { var cameraProviderFuture = ProcessCameraProvider.GetInstance(this); cameraProviderFuture.AddListener(new Runnable(() => { // Used to bind the lifecycle of cameras to the lifecycle owner var cameraProvider = (ProcessCameraProvider)cameraProviderFuture.Get(); // Preview var preview = new Preview.Builder().Build(); preview.SetSurfaceProvider(viewFinder.CreateSurfaceProvider()); // Take Photo this.imageCapture = new ImageCapture.Builder().Build(); // Frame by frame analyze var imageAnalyzer = new ImageAnalysis.Builder().Build(); imageAnalyzer.SetAnalyzer(cameraExecutor, new LuminosityAnalyzer(luma => Log.Debug(TAG, $"Average luminosity: {luma}") )); // Select back camera as a default, or front camera otherwise CameraSelector cameraSelector = null; if (cameraProvider.HasCamera(CameraSelector.DefaultBackCamera) == true) { cameraSelector = CameraSelector.DefaultBackCamera; } else if (cameraProvider.HasCamera(CameraSelector.DefaultFrontCamera) == true) { cameraSelector = CameraSelector.DefaultFrontCamera; } else { throw new System.Exception("Camera not found"); } try { // Unbind use cases before rebinding cameraProvider.UnbindAll(); // Bind use cases to camera cameraProvider.BindToLifecycle(this, cameraSelector, preview, imageCapture, imageAnalyzer); } catch (Exception exc) { Log.Debug(TAG, "Use case binding failed", exc); Toast.MakeText(this, $"Use case binding failed: {exc.Message}", ToastLength.Short).Show(); } }), ContextCompat.GetMainExecutor(this)); //GetMainExecutor: returns an Executor that runs on the main thread. }
// Declare and bind preview, capture and analysis use cases private void BindCameraUseCases() { // Get screen metrics used to setup camera for full screen resolution var metrics = new DisplayMetrics(); viewFinder.Display.GetRealMetrics(metrics); Log.Debug(Tag, "Screen metrics: " + metrics); var screenAspectRatio = AspectRatio(metrics.WidthPixels, metrics.HeightPixels); Log.Debug(Tag, "Preview aspect ratio: " + screenAspectRatio); var rotation = viewFinder.Display.Rotation; // CameraProvider if (cameraProvider == null) { throw new Java.Lang.IllegalStateException("Camera initialization failed."); } // CameraSelector var cameraSelector = (new CameraSelector.Builder()).RequireLensFacing(lensFacing).Build(); // Preview preview = new Preview.Builder() // We request aspect ratio but no resolution .SetTargetAspectRatio(screenAspectRatio) // Set initial target rotation .SetTargetRotation((int)rotation) .Build(); // ImageCapture imageCapture = new ImageCapture.Builder() .SetCaptureMode(ImageCapture.CaptureModeMinimizeLatency) // We request aspect ratio but no resolution to match preview config, but letting // CameraX optimize for whatever specific resolution best fits our use cases .SetTargetAspectRatio(screenAspectRatio) // Set initial target rotation, we will have to call this again if rotation changes // during the lifecycle of this use case .SetTargetRotation((int)rotation) .Build(); // ImageAnalysis imageAnalyzer = new ImageAnalysis.Builder() // We request aspect ratio but no resolution .SetTargetAspectRatio(screenAspectRatio) // Set initial target rotation, we will have to call this again if rotation changes // during the lifecycle of this use case .SetTargetRotation((int)rotation) .Build(); // The analyzer can then be assigned to the instance imageAnalyzer.SetAnalyzer(cameraExecutor, new LuminosityAnalyzer( (double luma) => { // Values returned from our analyzer are passed to the attached listener // We log image analysis results here - you should do something useful // instead! Log.Debug(Tag, "Average luminosity: " + luma); }) ); // Must unbind the use-cases before rebinding them cameraProvider.UnbindAll(); try { // A variable number of use-cases can be passed here - // camera provides access to CameraControl & CameraInfo camera = cameraProvider.BindToLifecycle( (ILifecycleOwner)this, cameraSelector, preview, imageCapture, imageAnalyzer); // Attach the viewfinder's surface provider to preview use case preview?.SetSurfaceProvider(viewFinder.CreateSurfaceProvider()); } catch (Java.Lang.Exception exc) { Log.Error(Tag, "Use case binding failed: " + exc); } }