Custom photography function in CameraAPI, photography by cameraapi
A few days ago, the project needed to use CameraAPI to define the camera. The previously used QR code also needed to write the underlying code. Therefore, I would like to summarize some things about using CameraAPI. Currently, the official documents of JDK and later versions no longer recommend using the camera package but the camera2 package, but this time we will talk about the use of camera first, and I will talk about camera2 later.
First, add camera permissions. In the list file, you must add the camera hardware permissions and usage functions. The functions can be selectively placed according to project requirements.
1 <uses-permission android: name = "android. permission. CAMERA"/> 2 <! -- Use camera hardware functions --> 3 <uses-feature android: name = "android. hardware. camera"/> 4 <! -- Auto Focus function --> 5 <uses-feature android: name = "android. hardware. camera. autofocus"/> 6 <! -- Flashlight function --> 7 <uses-feature android: name = "android. hardware. camera. flash"/> 8 <! -- Front camera --> 9 <uses-feature android: name = "android. hardware. camera. front"/>
For more information about permissions and related functions, see http://www.cnblogs.com/BobGo/articles/5646751.html;
I need two functions in the project. One is to add an ImageView layer to the SurfaceView of the display camera to draw different mask layers on the ImageView; another feature is to display and save pictures after the camera takes a photo.
The first is the simple use of the camera. Here there may be a problem of deformation in the preview of the camera in SurfaceView. The following describes the solution:
1 SurfaceHolder surfaceHolder = surfaceView.getHolder();2 surfaceHolder.addCallback(this);3 surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
Implement the SurfaceHolder. Callback interface in the current class, and rewrite the three methods surfaceCreated (), surfaceChanged (), and surfaceDestroy (). These three methods are the corresponding life cycle of SurfaceView;
InSurfaceCreated ()ExecutedCamera. open ()Return a Camera object, open the Camera hardware, andSurfaceDestroy ()The Camera object calls release () to release the Camera.SurfaceChanged (), Set the camera parameters, whereGetBestSize ()This algorithm is the most suitable size for mobile phone camera hardware. I did not use this algorithm before and directly set the size, resulting in deformation of the picture displayed by SurfaceView when the test machine was running.
1 @ Override 2 public void surfaceCreated (SurfaceHolder holder) {3 camera = Camera. open (); 4} 5 6 @ Override 7 public void surfaceChanged (SurfaceHolder holder, int format, int width, int height) {8 // the width and height of the Surface have been obtained, set the Camera Parameter 9 Camera. parameters parameters = camera. getParameters (); 10 Camera. size size = getBestSize (parameters. getSupportedPreviewSizes (); 11 int w = size. width; 12 int h = size. he Ight; 13 parameters. setPreviewSize (w, h); 14 parameters. setPictureSize (w, h); 15 // List <Camera. size> vSizeList = parameters. getSupportedPictureSizes (); 16 // for (int num = 0; num <vSizeList. size (); num ++) {17 // Camera. size vSize = vSizeList. get (num); 18 //} 19 // if (t? His. getResources (). getConfiguration (). orientation! = Configuration. ORIENTATION_LANDSCAPE) {20 // force portrait mode 21 parameters. set ("orientation", "portrait"); 22 // available for use above 2.2, Preview display rotate 9023 // parameters. setRotation (90); 24 camera. setDisplayOrientation (90); 25 //} else {26 // parameters. set ("orientation", "landscape"); 27 // 28 // camera can be used for more than 2.2. setDisplayOrientation (90); 29 //} 30 camera. setParameters (parameters); 31 try {32 // set to display 33 camera. setPreviewDisplay (holder); 34} catch (IOException exception) {35 camera. release (); 36 camera = null; 37} 38 // start previewing 39 camera. startPreview (); 40 // set autofocus 41 camera. autoFocus (new Camera. autoFocusCallback () {42 @ Override43 public void onAutoFocus (boolean success, Camera camera) {44 if (success) {45 // if success is true, the focus is successful, changed focus status image 46} 47} 48}); 49} 50 51 private Camera. size getBestSize (List <Camera. size> supportedPreviewSizes) {52 Camera. size largestSize = supportedPreviewSizes. get (0); 53 int largestArea = supportedPreviewSizes. get (0 ). height * supportedPreviewSizes. get (0 ). width; 54 for (Camera. size s: supportedPreviewSizes) {55 int area = s. width * s. height; 56 if (area> largestArea) {57 largestArea = area; 58 largestSize = s; 59} 60} 61 return largestSize; 62 63} 64 65 @ Override66 public void surfaceDestroyed (SurfaceHolder holder) {67 // release mobile phone camera 68 camera. release (); 69}
You can alsoSurfaceChanged ()Set flash and other functions:
1 parameters.setFlashMode(isChecked?Camera.Parameters.FLASH_MODE_ON:Camera.Parameters.FLASH_MODE_OFF);
Finally, it is called in the click listener for video recording.TakePicture (Camera. ShutterCallback, Camera. PictureCallback)Function to complete the photo. In this function, you can use four callback interfaces,ShutterCallbackIt is the callback of the shutter press. Here we can set operations such as playing the "click" sound. There are threePictureCallbackInterface to correspond to three image data parts: the original image, the scaling and compression image, and the JPG image.PictureCallbackInterfaceVoid onPictureTaken (byte [] data, Camera camera)The Three callbacks corresponding to the three pieces of data are called in the Parameter order. Generally, we only care about JPG image data. At this time, the first twoPictureCallbackInterface parameters can be directly transmittedNull;
Each callTakePicture ()After obtaining the image, the camera stops previewing. If you want to continue taking the image, you needPictureCallbackOfOnPictureTaken ()At the end of the function, the Camera object is called again.StartPreview ()Function,CameraThe object must be called proactively.StopPreview ()Stop preview;
The second feature is video image display and storage. Two problems may occur in this feature. One is horizontal screen display of the image, the other is to save the ImageView mask layer above SurfaceView to the user's mobile phone to achieve the effect similar to image synthesis;
The problem about horizontal screen display of pictures is that Android officials believe that the mobile phone horizontal screen is the correct way for the camera to open, so the saved pictures are saved on the horizontal screen, so if you want to display pictures on the vertical screen, you need to rotate the image 90 degrees clockwise and adjust it to the portrait display mode. The specific code is as follows:
1 private void setImageByte(ImageView showImage, byte[] data) {2 Bitmap bitmap= BitmapFactory.decodeByteArray(data, 0, data.length);3 showImage.setImageBitmap(bitmap);4 Matrix matrix = showImage.getImageMatrix();5 matrix.setRotate(90);6 showImage.setImageBitmap(Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true));7 }
Another problem is to solve the problem of saving the content of the two controls at the same time. In fact, it is very easy to think of the method. to customize a sub-layout of FrameLayout, add only one method to the layout.
1 public Bitmap getBitmap () {2 // set cache 3 setDrawingCacheEnabled (true); 4 buildDrawingCache (); 5 // obtain the image of the current screen from the cache 6 return getDrawingCache (); 7}
In the xml layout used above, the layout is used as the parent Control for saving the image at the same time.
Finally, to save the merged image in java code, you only need to instantiate the custom FrameLayout object and call getBitmap () to return the merged Bitmap object;
So our functions can be fully implemented.