2.1 Create a Live Camera Preview
In this lesson, you’ll create a live camera preview user interface. You’ll learn how to use a
TextureView to render the camera’s output, how to determine the orientation of your camera’s sensor, and how to initialize most of the camera-related object instances you’ll need for the rest of this course.
1.Introduction2 lessons, 06:13
2.Using the Camera2 API2 lessons, 26:08
3.Using Android GPUImage2 lessons, 10:44
4.Conclusion1 lesson, 00:30
2.1 Create a Live Camera Preview
Hello and welcome back to this short course about using the camera 2 API. In this lesson, we are going to create a live camera preview. The camera 2 API is as I said earlier, very powerful. However, it also expects you to handle a lot of low level details yourself, so prepare yourself to write lots of code now. Start by opening activity_main.xml. Select the hello world text view that was generated by default and deleted. Switch to text mode now and add a TextureView to the layout. Set its width and height to wrap content. This is the view that will display the live camera preview. So, set its ID to preview and place it at the center of the layout by setting its center in parent attribute to true. Next, add a floating action button tag and set it's width and height to wrap content. Set its source attribute to the camera icon we added earlier. The color of the icon is currently black, but I wanted white, so set that int attribute to @android:color/white. Finally, set it's ID to fab. This is the bottom the users will press to take a photo. Additionally, to allow the camera preview to fool the screen completely, I'm going to remove these paddings. I'm also going to set the background of this layout to black. Okay, now we'll be placing the floating action button on the bottom right corner of the screen. So, set align parent bottom to true and also set align parent right to true. To make it look good at that position, give it a margin right of activity horizontal margin. And also, give it a margin bottom of activity vertical margin. Here is what our activity looks like now. Let's go back to mainactivity.java. Here, replace both of these to do comments we added in the previous lesson, with calls to a method called initialize UI. This method doesn't exist, so create it. Inside this method, we're going to initialize all the UI components. And then, call a few methods to initialize the camera and start the preview. First, create member variables for the text of view and the floating action button we add it to the layout. Then inside initialize UI, use the find view by ID method to initialize them. Make sure that you typecast the results of find view by ID appropriately. Next call a method called initializeCamera. This method doesn't exist yet. So I created it. Let us now add a few more member variables to have a class. They're going to be needing a CameraManager object to manage all the camera hardware available to us. Then we'll need a CameraDevice object. Which will act as a reference to the camera we will be using. We'll also need a string containing the id of the camera in this course. We'll be working only with the back camera. So I'll call this back camera. And finally we'll need a camera capture session object to manage our camera session. Apart from these camera related objects, let us add a handler object. You're going to see later that this is going to be used by most of the methods of the camera capture session object. And now, we must define the width and height of our preview. Ideally, you would determine the preview width and height based on the width and height of the user's device. However for now, I'll be using a verdict and height of 640 pixels and 480 pixels. This resolution is supported by most cameras. And should look okay on most screens. So I answered in the preview word to 640. And set the preview height to 480. We'll be generating a few debug messages in this app and then need a log tag. So create a static final string variable called TAG. And set its value to MY CAMERA. All right, let's get back to the initialized camera method. Now initialize the camera manager first, using the Get system service method. Passing camera service as an argument to it. Let us now get a list of all the cameras available to us. To do so, call the Get Camera ID list method of the camera manager object. This method can through a camera access exception. So you must set around it with a try catch. As I said earlier, I will be using only the back camera. So we must now determine the ID of the back camera. To do so, loop through the camera. Inside the loop, get the characteristics of the current camera. Using the Get camera characteristics method of the camera manager object. To take of this is the back camera the value of the camera characteristic start lens facing key. And then check if it is equal to camera characteristics start lens facing back. If this condition is true, it means that we have found the back camera. So assign the camera string to the back camera field. We don't have to do anything else here. So say return. And now, lets configure the texture view. So that it can display the camera preview inside it. Let's do that inside a method called initialize preview. You need the method. Here we need to specify the veg and height of the text view. Now we have already decided that the preview width and preview height should 640 pixels and 480 pixels, respectively. However, we can't use those values directly. Because in almost all devices, the camera sensor is rotated by either 90 degrees or 270 degrees. Let me now show you how you can determine the angle or orientation of your camera sensor. So first, call cameraManager.getCameraCharacteristics. And pass backCamera to it. Next, get the value of camera characteristics.sensor_orientation. Don't forget to wrap this in a try catch block. Here, let us simply log the value of the orientation as a debug message using the log.d method. Don't forget to pass the tag as the first argument of the method. Now if you run your app on your device, you should be able to see the orientation of your camera sensor is. As you can see, in my case, it is ninety. Because of this angle, you must see the values of the preview and height to make sure that the preview is not distorted. So call get layout patterns of the preview text of view. And set it's width to preview height. Similarly, set its height to preview width. And for these values to take effect, call the request layout method of the text of view. We must now add a listener to add texture view in order to determine van surface texture is available. So call the set surface texture listener method. And pass a new textview.surfacetexturelistenerobject to it. Inside the on surface texture available method, called a method call start preview. Again, this is a new matter and created. It's now time to open our camera, using the openCamera method of the camera manager. So past the ID of the camera to it. Which is back camera, in our case. Along with the callback object and our handler object. The handler object has not been initialized yet. So, do so now using its constructor. Next, initialize the callback object using its constructor. Android studio should automatically generate stubs for the abstract methods of CameraDevice.StateCallback. Now you can see that Android Studio expects us to catch a security exception while opening the camera. So add a try catch block around it. Additionally, we must catch the camera access exception. So add another catch class. Okay, lets get back to the call back object. Inside the onOpen matter, we have access to the camera device that was opened. Assign it to the camera device object of our class. So that we can use it later in other methods. We can now use the camera device to create a new capture station. As its first argument, this method expects a list of services. So call the array start as list method. And pass the surface of the previews surface texture to it. As the next argument, pass a new_CameraCaptureSession.StateCallback object. And, as the last argument, pass the handler. Again, you must handle the camera access exception using a try catch block. Now inside the onConfigured method of this object, we have access to the newly created camera capture session object. Assign it to the CameraCaptureSession variable of our activity. So that we can use it later In other methods. We'll be telling the cameraCaptureSession object what we want to do with the camera using capture request objects. So add a capture request.build an object to the activity. We'll be using this builder object to create new capture request objects. Initialize the request builder using the camera.Device.createCapture request method. And as an argument to it, pass the preview template. Because we want a live preview now. Again handle the camera access exception. During the preview, the camera should be continuously adjusting its focus. So that the preview looks sharp. Therefore, we must set the value of capture request.control AF mode. Which is short for control auto focus mode. To capture request dot control AF mode continuous picture. And then we must specify the target of the capture request using the ADD target method. For now, the target is the surface of the preview text of you. So you can just copy and paste this. For the live preview, the camera must be continuously capturing frames. Therefore, call the set repeating request method. As the first argument pass the result of requestBuilder.build. The second argument must be a call back object. However we don't need to listen for any call back events here. So pass As the last argument pass the handler object. At this point, I will live preview user interface is ready. But before we move on let us make sure that we release the camera resources when our app exits. So override the onPause method of the activity. And inside it first call the close method of the cameraCaptureSession object. And then call the close method of the camera device object. Okay if you run the app now you should be able to see the output of your back camera inside the activity. You now know how to display a live preview Preview using the camera to API. We had to write a lot of code but that's how the camera to API works and all that code is really necessary and unavailable. In the next lesson I will show you how to actually take photos. Thanks for watching.