In Android 5.0 (SDK 21), Google uses Camera2 instead of the camera interface. Camera2 has made great changes in interface and architecture,
But for well-known reasons, we also have to develop based on the Android 4.+ system. This article describes the development of the camera interface and how to use it, through this article, you will fully learn the camera interface development process.
This text and githubpages original text are my original
Paste_image.png Call system Camera/other app to complete shooting operation
If your app's needs are just 调用摄像头拍照并拿到照片
, the old driver's advice is not to implement the camera module, which is more water depth inside the pit. You can use intent to call the system camera or a third-party photo-capable app to take pictures and get back the photo data.
Create a intent that specifies one of the two shooting types:
MediaStore.ACTION_IMAGE_CAPTURE
Take photos;
MediaStore.ACTION_VIDEO_CAPTURE
Shooting video;
Intent Intent = new Intent (mediastore.action_image/video_capture);
The general process startActivityForResult()
and onActivityResult()
it is not expressed. Tell me about the intent parameters for taking photos.
The first is to set the address of the returned data after shooting:
Intent.putextra (Mediastore.extra_output, Your-store-uri);
MediaStore.EXTRA_OUTPUT
The parameter is used to specify the storage path of the photo/video after the shot is completed. You can use the android default storage photo directory to save:
Environment.getexternalstoragepublicdirectory (Environment.directory_picture)
It can also be any other storage directory you like. If you use the app's internal directory, some temporary files such as photos and uploads of the avatar file, after processing is completed, remember to delete it. The advantage of this is that it reduces the amount of storage space used by the app, and mobile users are particularly fond of removing and cleaning up space for apps that occupy large storage space. If you have to save large volumes of files, you can use a public space to store them, throw them away, and the private space will save only the app configuration data.
Other camera settings, such as the size of the designated photo shoot, photo quality, etc., to be updated later in the article.
TODO is the biggest lie in the programming world.
Using camera development
PhotographyFunction
Using the camera API to develop a camera module takes a lot of effort. Here are the methods and processes that describe my use of the camera API in developing Nextqrcode projects.
1. Declaring camera permissions in Android manifest.xml
The first step in development is to declare the right to use the camera in the Android manifest.xml file:
<uses-permission android:name="android.permission.CAMERA" />
Some students forget to declare permissions when they develop, and the runtime app may crash. In addition, the following two feature declarations are added:
<uses-feature android:name="android.hardware.camera" android:required="true"/><uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
required
property is a description of whether this attribute must be met. Let's say the example is set to require that you have a camera device but you don't have autofocus.
These two claims are optional and are used for App Store (Google Play) filtering does not support cameras and devices that do not support autofocus.
In addition, when you save a photo, you need to write to the storage, you need to add a read-write storage permission statement:
<uses-permission android:name="android.permission.WEITE_EXTERNAL_STORAGE" />
2. Turn on the camera device
Now the market for mobile phones/tablets and other consumer products basic standard two cameras. such as Huawei P9, but also has a front-facing dual camera. To tell the truth, I'm curious about the experience of developing a dual-camera app. Before opening the camera device, get the number of camera devices on the current device. If your development needs include pre-and post-switch camera functions, you can get the number of cameras to determine if there is a rear camera.
int cameras = Camera.getNumberOfCameras();
This interface returns a value of the number of cameras: non-negative integers. Correspondingly, the camera serial number is: cameras - 1
. For example, on a mobile device with a front and back camera, the return result is that the 2
first camera cameraId
0
, usually corresponding to the big camera behind the phone, the second camera cameraId
1
, usually corresponding to the phone's front-end selfie camera;
The camera is a hardware device resource that needs to be opened before using the device resource and can be opened via an interface Camera.open(cameraId)
. Refer to the following code:
public static Camera openCamera(int cameraId) { try{ return Camera.open(cameraId); }catch(Exception e) { return null; }}
Attention
Turning on the camera device may fail, and you must check that the open operation is successful. There are two possible reasons to open a failure: one is that there is no camera on the device where the app is installed, such as some tablet or special Android device, cameraId
and the corresponding camera is being used, and maybe an app is using it to record video in the background.
3. Configure camera parameters
After you turn on the camera device, you will get a camera object and the 独占
device resource.
Camera.getParameters()
the interface allows you to obtain the default configuration parameters for the current camera device. Here are some of the parameters I can understand:
Flash configuration parameters, you can Parameters.getFlashMode()
obtain the current camera's flash configuration parameters via the interface:
Camera.Parameters.FLASH_MODE_AUTO
Auto mode, automatically turn on the flash when the light is darker;
Camera.Parameters.FLASH_MODE_OFF
Turn off the flash;
Camera.Parameters.FLASH_MODE_ON
Flash when taking pictures;
Camera.Parameters.FLASH_MODE_RED_EYE
Flash parameters, red-eye mode, Popular science: red-eye protection;
The focus mode configuration parameter can be Parameters.getFocusMode()
obtained via the interface:
Camera.Parameters.FOCUS_MODE_AUTO
Auto focus mode, photography small white special mode;
Camera.Parameters.FOCUS_MODE_FIXED
Fixed focus mode, shooting old driver mode;
Camera.Parameters.FOCUS_MODE_EDOF
The mode of depth of field, the most favorite mode of literary female youth;
Camera.Parameters.FOCUS_MODE_INFINITY
Long-term mode, the pattern of the scene;
Camera.Parameters.FOCUS_MODE_MACRO
Micro-Coke mode, shooting floret grass small ant special mode;
The scene mode configuration parameters can be Parameters.getSceneMode()
obtained through the interface:
Camera.Parameters.SCENE_MODE_BARCODE
Scan the barcode scene, Nextqrcode item will be judged and set as this scene;
Camera.Parameters.SCENE_MODE_ACTION
Action scene, is to capture the fast running athletes, cars and other scenes used;
Camera.Parameters.SCENE_MODE_AUTO
automatic selection of scenes;
Camera.Parameters.SCENE_MODE_HDR
High dynamic contrast scene, usually used to photograph the bright and bright shades such as sunset;
Camera.Parameters.SCENE_MODE_NIGHT
Night scene;
The Camera API provides a number of parameter interfaces for developers to set up and, if necessary, to read through the relevant API documentation.
In the Nextqrcode project, you need to use the auto-focus feature. There may be no AF on some models (although relatively uncommon), this situation needs to be handled.
4. Set the camera preview direction
The camera preview needs to set the correct preview direction in order to properly display the preview screen, otherwise the preview screen will be badly squeezed.
Under normal circumstances, if we need to know the screen orientation of the device, it can be Resources.Configuration.orientation
obtained by. Android screen orientation has "vertical screen" and "horizontal screen" two, the corresponding values are ORIENTATION_PORTRAIT
and ORIENTATION_LANDSCAPE
. But the camera device direction is somewhat special, set the preview direction of the interface Camera.setDisplayOrientaion(int)
parameters are in terms of the unit, and can only be one of 0,90,180,270
them, by default 0
, refers to the left side of the phone is the camera overhead screen. Remember can only be [0, 90, 180, 270] one of them, input other angle value will be error.
If you want the camera to follow the direction of the device, the top of the preview screen remains just above, the following code is for reference:
public static void followScreenOrientation(Context context, Camera camera){ final int orientation = context.getResources().getConfiguration().orientation; if(orientation == Configuration.ORIENTATION_LANDSCAPE) { camera.setDisplayOrientation(180); }else if(orientation == Configuration.ORIENTATION_PORTRAIT) { camera.setDisplayOrientation(90); }}
5. Preview view and take photos
We generally use SurfaceView
the preview view as a camera, you can also use texture. Get Surfaceholder in Surfaceview and setPreviewDisplay()
preview via interface settings. After setting the Preview view, Be sure to remember the following two points:
- Invoke
startPreview()
the method to start the preview, otherwise the Preview view will not display anything;
- The photo operation needs to be
startPreview()
called after the method executes;
- Preview view stops previewing each time you take a photo. So take pictures continuously, need recall
startPreview()
to restore preview;
The camera accepts a Surfaceholder interface, which can be obtained through surfaceholder.callback. We can implement the camera preview effect by inheriting Surfaceview. In the Nextqrcode project, the implementation of the LiveCameraView
class, it has implemented the camera preview needs to process, very concise class, the following is its full source:
PublicClassLivecameraviewExtendsSurfaceviewImplementsSurfaceholder.Callback {PrivateFinalstatic String TAG = LiveCameraView.class.getSimpleName ();Private Camera Mcamera;Private Surfaceholder Msurfaceholder;PublicLivecameraview(context context, AttributeSet attrs,int defstyleattr) {Super (context, attrs, defstyleattr); Msurfaceholder =This.getholder (); Msurfaceholder.addcallback (this); }@OverridePublicvoidsurfacecreated(Surfaceholder Holder) {LOG.D (TAG,"Start preview display[surface-created]"); Startpreviewdisplay (holder); }@OverridePublicvoidSurfacechanged(Surfaceholder holder,int format,int width,int height) {if (msurfaceholder.getsurface () = =NULL) {Return } cameras.followscreenorientation (GetContext (), Mcamera); LOG.D (TAG,"Restart preview display[surface-changed]"); Stoppreviewdisplay (); Startpreviewdisplay (Msurfaceholder); }PublicvoidSetcamera(Camera camera) {Mcamera = camera;Final Camera.parameters params = Mcamera.getparameters (); Params.setfocusmode (Camera.Parameters.FOCUS_MODE_AUTO); Params.setscenemode (Camera.Parameters.SCENE_MODE_BARCODE); }PrivatevoidStartpreviewdisplay(Surfaceholder Holder) {Checkcamera ();try {mcamera.setpreviewdisplay (holder); Mcamera.startpreview ();}catch (IOException e) {log.e (TAG,"Error while START preview for Camera", e); } }PrivatevoidStoppreviewdisplay() {Checkcamera ();try {Mcamera.stoppreview ();}catch (Exception e) {log.e (TAG, "Error while STOP preview for Camera", e); }} private void checkcamera () {if (Mcamera = = null) {throw new illegalstateexception ( "Camera must is set when Start/stop preview, call <setcamera (Camera) > To set"); }} @Override public void surfacedestroyed (SurfaceHolder holder) { LOG.D (TAG, "Stop preview display[surface-destroyed]"); Stoppreviewdisplay ();}}
From the code above you can see that the core code of Livecameraview is SurfaceHolder.Callback
the callback: Start/Stop preview action on creation/destruction. In the Livecameraview class, we used the view lifecycle callback to automate the management of preview lifecycle controls:
- Automatically turn on preview when Surfaceview is created;
- Close preview when Surfaceview is destroyed;
- Resets the preview when the Surfaceview size is changed;
Preview view needs to be aware of the size of the preview output screen. The camera output screen only supports part sizes. For the Dimensions section, update later.
After you enable Preview view, you can Camera.takePicture()
take a photo with the method, and the returned photo data is obtained through the callback interface. An takePicture()
interface can get three types of photos:
- The first, Shuttercallback interface, is immediately recalled at the moment of shooting, usually for playing "click" sound;
- The second, Picturecallback interface, returns uncompressed raw type photos;
- The third, Picturecallback interface, returns the compressed JPEG type photo;
We use the third parameter, the image precision of JPEG type photo can satisfy the need of recognizing QR code. In the Nextqrcode project, the data format of the zxing recognition QR code is bitmap, and the byte array can be converted to bitmap conveniently and conveniently by bitmapfactory.
public abstract class bitmapcallback implements camera. picturecallback { @Override public void onpicturetaken (byte[] data, camera camera) {Onpicturetaken (Bitmapfactory.decodebytearray (Data, 0, Data.length)); } public abstract void onpicturetaken
For a detailed description of bitmap in Android, see the article Android:bitmap and drawable this little thing.
If you need to save the photo as a file, you can refer to the implementation of this class: Filephotocallback.java
6. Release the camera device
When you open a camera device, it means that your app is on the 独占
device and other apps won't be able to use it. So when you don't need a camera device, remember to call the release()
method to release the device and then reopen it when you use it, which doesn't cost much. You can choose to stopPreview()
release the camera device after that.
Additional tool Code Implementation 1-determine if the phone device has a camera device
public static boolean hasCameraDevice(Context ctx) { return ctx.getPackageManager() .hasSystemFeature(PackageManager.FEATURE_CAMERA);}
2-Determine if auto focus is supported
public static boolean isAutoFocusSupported(Camera.Parameters params) { List<String> modes = params.getSupportedFocusModes(); return modes.contains(Camera.Parameters.FOCUS_MODE_AUTO);}
How to use camera correctly to develop
Video CaptureFunction
I'm sorry, I've never really studied this.
Provide a link address for your reference: Camera development video Capture
About CAMERA2
The development course of the subsequent re-update Camera2
Chen
Links: https://www.jianshu.com/p/7dd2191b4537
Source: Pinterest
Copyright belongs to the author. Commercial reprint please contact the author for authorization, non-commercial reprint please specify the source.
"Turn" Android camera development detailed