CameraViewPlus

The aim of this library is to let you integrate camera features to your app, in case using Intent to launch default Camera cannot fulfill your requirements, such as overlaying images to your Camera preview.

This is a fork from Google's CameraView.Based on the original one, the following has been done (As per Version 0.9.4):

Resolved some bugs

Implemented zoom feature (Configurable since v0.9.5)

Improved API friendliness

Changed return image from byte[] to Bitmap, with rotation degrees

Added camera event listeners

Allow force fallback to Camera1

Write this documentation...

NEW! 0.9.0 Callback to get each frame of camera preview in high FPS

NEW! 0.9.4 Configurable Preview and Capture image max resoultion

When do I need this library?

Surprising, I found that there are not much CameraView library out there.I think it is because in most use-cases, we just need to launch the default camera by Intent and get the returned URI.As far as I know, unless you want to customize the layout of the "Camera Activity" (e.g. overlaying a photoframe on the preview), it is rare that you need to implement your own CameraView.

Why this library?

For those libraries I found out there, such as CameraView and Fotoapparat, although they are really good libraries, up to date and with a lot of revisions, I still encountered various minor problems.

For example, distorted aspect ratios in some devices, low FPS in returned preview frame, wrong orientation of returned preview frame, not using new Camera 2 API (Which produces a sound when taking pictures, less smooth zooming), insufficient documentations, etc...

Although this library does not have as much functionalities and flexibilities the above 2 libraries provided, but if what you want is simply a CameraView that is able to show a correct preview, take a correct picture in a correct orientation, then you are at the right place (I hope).

Recently I used it to create a real-time face detection app, overlaying images onto those faces and take a picture with those overlays, with correct orientations no matter how you hold the device. This might be more difficult than you imagined!

Callback when focus is locked (i.e. You can play animation, if you like, when focus is locked)

NEW! 0.9.0 Callback of each preview frame, passed to you in byte[] with width, height and rotation degrees

NEW! 0.9.4 Configurable Preview and Capture image max resoultion

What this library does NOT offer but you are probably expecting

Handle runtime permission for you (You should not expect a View is responsible for this)

Tap to focus (Hard to implement... May be in the future!)

Prerequisite

This library only supports, and tested, in a portrait activity.User can hold the device in any orientations he/she wants, the output image has correct orientation, but your activity configuration should never be rotated to landscape.

cameraAspectRatio is width/height in LANDSCAPE mode. (Thus width is the LONGER side)

maximumWidth and maximumPreviewWidth will limit the longer length of the resolution. For example, if you set aspectRatio="16:9" and maximumWidth="2000", 3200*1800 will not be used, but 1920*1080 will be used.

If useHighResPicture is set to true && your device supports it, it will override maximumWidth and will use only super high resolution.

IMPORTANT: Please use your own ViewGroup to contain CameraView. Otherwise the preview might over-expand to out of what you may expect. I did not spend time on trying to fix this.

Step 3: Starting CameraView in your activity

This library does not help you to check runtime permission!Remember to check it by yourself before calling cameraView.start().

Step 5: Taking picture

cameraView.takePicture();

Optional: Switching camera facing

cameraView.switchCamera();

Optional: Advanced usage

Pinch zooming sensitivity

cameraView.setPixelsPerOneZoomLevel(100) //Default value is 80

The number of pixels represents the distance (in pixels) between your fingers that need to change, in order for zoom level to increase or decrease by 1x.(With that said, Camera1 API does not expose such precise zoom ratio. So, if the device uses Camera1 API, the zoom level difference is discrete and hard to tell the exact ratio change.)

Getting each camera preview frame

This is useful if you need to process each frame, e.g. Perform some face detections.

maximumPreviewWidth will affect the width and height returned in onFrame().

As you can see, I am using Nv21Image.nv21ToBitmap() to convert the byte[] into a Bitmap.This is because the byte[] of frames are in NV21 formatting instead of JPEG. This is a must for a high FPS; and the only format of Camera1 API.

The native BitmapFactory cannot decode NV21 byte array.I made use of this library (EasyRS) to do the conversion from NV21 to Bitmap(ARGB).

Forcing to use Camera1

For any reason, if you want to fallback to Camera1 even for devices that supports Camera2 API, Before the construction of CameraView, (i.e. before onCreate() of the Activity that contains CameraView):

CameraViewConfig.isForceCamera1 = true;

Release Notes

(Release Notes are not avaiable before v0.9.4.)

v0.9.5

Added optional callback to get raw bytes[] instead of Bitmap. (#9)

Tried to resolve #4 orientation not detected if device does not have a magnetometer.

Merged #7 So that user can now disable zoom feature.

v0.9.4

Fixed aspect ratio not working in Camera2, which is an original bug here.

Implemented maximum preview width

Implemented maximum image width

Want to know more?

How does this library manage image's orientation?

In the original Google's CameraView, it uses OS's orientation (Whether the activity is portrait or landscape) to determine's the output image's orientation.

But this approach really sucks. All camera apps I know are defaulted to portrait mode (so that the activity will not be re-created when your rotate your device) to provide smoother UX.

At first (v0.7.0) I used EXIF attributes to read orientation from byte[]. But later I found that this does not always works.

So in v0.9.0 I abandoned the old method and implemented SensorEventListener to observe real time device orientation change. By reading the orientation value from the sensor, together with reading the camera's default orientation, a rotation degrees value is passed to you in both OnPictureTaken() and onFrame(). You can then rotate the bitmap by yourself using this value.

Why a shutter sound is played in some devices?

As far as I know, this happens if your device has API Level >= 21, but still using Camera1 API.This happens if