🚀 Big News:Socket Has Acquired Secure Annex.Learn More
Socket
Book a DemoSign in
Socket

cordova-plugin-camera-preview

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cordova-plugin-camera-preview - npm Package Compare versions

Comparing version
0.11.2
to
0.12.0
+8
-2
CHANGELOG.md
# Changelog
## MASTER BRANCH (RECOMMENDED) - UNRELEASED
- Nothing Yet
- Nothing yet
## v0.11.2 - February 12, 2020 - LATEST RELEASED VERSION
## v0.12.0 - May 4, 2020 - LATEST RELEASED VERSION
- [PR #605](https://github.com/cordova-plugin-camera-preview/cordova-plugin-camera-preview/pull/605) - Improve memory usage when capturing multiple photos for both Android and iOS
- [PR #587](https://github.com/cordova-plugin-camera-preview/cordova-plugin-camera-preview/pull/587) - Add video recording functionality for Android
- [PR #599](https://github.com/cordova-plugin-camera-preview/cordova-plugin-camera-preview/pull/599) - Use androidx package instead of legacy android support package
- [PR #606](https://github.com/cordova-plugin-camera-preview/cordova-plugin-camera-preview/pull/606) - Remove `android:required` from manifest to avoid conflict with other plugins
## v0.11.2 - February 12, 2020
- [PR #582](https://github.com/cordova-plugin-camera-preview/cordova-plugin-camera-preview/pull/582) - Add support for Android devices without Autofocus which can increase the amount of devices for which app installation is allowed by about (~4k at time of)

@@ -8,0 +14,0 @@ - [PR #583](https://github.com/cordova-plugin-camera-preview/cordova-plugin-camera-preview/pull/583) - Fix typescript error CameraPreview.d.ts is not a module

+1
-1
{
"name": "cordova-plugin-camera-preview",
"version": "0.11.2",
"version": "0.12.0",
"description": "Cordova plugin that allows camera interaction from HTML code for showing camera preview below or on top of the HTML.",

@@ -5,0 +5,0 @@ "keywords": [

<?xml version="1.0" encoding="UTF-8"?>
<plugin id="cordova-plugin-camera-preview" version="0.11.2" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<plugin id="cordova-plugin-camera-preview" version="0.12.0" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">

@@ -26,4 +26,3 @@ <name>cordova-plugin-camera-preview</name>

<preference name="ANDROID_SUPPORT_LIBRARY_VERSION" default="26+"/>
<framework src="com.android.support:exifinterface:$ANDROID_SUPPORT_LIBRARY_VERSION" />
<framework src="androidx.exifinterface:exifinterface:1.2.0" />

@@ -38,5 +37,7 @@ <config-file target="res/xml/config.xml" parent="/*">

<config-file target="AndroidManifest.xml" parent="/manifest">
<uses-feature android:name="android.hardware.camera" android:required="true"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.autofocus"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</config-file>

@@ -43,0 +44,0 @@

+38
-161

@@ -9,3 +9,3 @@ # Cordova Plugin Camera Preview

**PR's are greatly appreciated. Maintainer(s) wanted.**
**PR's are greatly appreciated.**

@@ -15,12 +15,14 @@ # Features

<ul>
<li>Start a camera preview from HTML code.</li>
<li>Maintain HTML interactivity.</li>
<li>Drag the preview box.</li>
<li>Set camera color effect.</li>
<li>Send the preview box to back of the HTML content.</li>
<li>Set a custom position for the camera preview box.</li>
<li>Set a custom size for the preview box.</li>
<li>Set a custom alpha for the preview box.</li>
<li>Start a camera preview from HTML code</li>
<li>Take Photos and Snapshots</li>
<li>Maintain HTML interactivity</li>
<li>Drag the preview box</li>
<li>Set camera color effect</li>
<li>Send the preview box to back of the HTML content</li>
<li>Set a custom position for the camera preview box</li>
<li>Set a custom size for the preview box</li>
<li>Set a custom alpha for the preview box</li>
<li>Set the focus mode, zoom, color effects, exposure mode, white balance mode and exposure compensation</li>
<li>Tap to focus</li>
<li>Record Videos</li>
</ul>

@@ -57,3 +59,4 @@

#### iOS Quirks
If you are developing for iOS 10+ you must also add the following to your config.xml
1. It is not possible to use your computers webcam during testing in the simulator, you must device test.
2. If you are developing for iOS 10+ you must also add the following to your config.xml

@@ -72,10 +75,6 @@ ```xml

#### Android Quirks (older devices)
When using the plugin for older devices, the camera preview will take the focus inside the app once initialized.
In order to prevent the app from closing when a user presses the back button, the event for the camera view is disabled.
If you still want the user to navigate, you can add a listener for the back event for the preview
(see <code>[onBackButton](#onBackButton)</code>)
#### Android Quirks
1. When using the plugin for older devices, the camera preview will take the focus inside the app once initialized. In order to prevent the app from closing when a user presses the back button, the event for the camera view is disabled. If you still want the user to navigate, you can add a listener for the back event for the preview (see <code>[onBackButton](#onBackButton)</code>)
# Methods

@@ -121,3 +120,3 @@

When setting the toBack to true, remember to add the style below on your app's HTML or body element:
When setting `toBack` to true, remember to add the style below on your app's HTML or body element:

@@ -130,4 +129,8 @@ ```css

When both tapFocus and tapPhoto are true, the camera will focus, and take a picture as soon as the camera is done focusing.
When both `tapFocus` and `tapPhoto` are true, the camera will focus, and take a picture as soon as the camera is done focusing.
If you capture large images in Android you may notice that performace is poor, in those cases you can set `disableExifHeaderStripping` to true and instead just add some extra Javascript/HTML to get a proper display of your captured images without risking your application speed.
When capturing large images you may want them to be stored into a file instead of having them base64 encoded, as enconding at least on Android is very expensive. With the feature `storeToFile` enabled the plugin will capture the image into a temporary file inside the application temporary cache (the same place where Cordova will extract your assets). This method is better used with `disableExifHeaderStripping` to get the best possible performance.
### stopCamera([successCallback, errorCallback])

@@ -534,143 +537,32 @@

# storeToFile
### startRecordVideo(options, cb, [errorCallback])
When capturing large images you may want them to be stored into a file instead of having them
base64 enconded, as enconding at least on Android is very expensive. With the feature storeToFile enabled
the plugin will capture the image into a temporary file inside the application temporary cache (the same
place where Cordova will extract your assets). This method is better used with *disableExifHeaderStripping*
to get the best possible performance.
*Currently this feature is for Android only. A PR for iOS support would be happily accepted*
<info>Start recording video to the cache.</info><br/>
Example:
```html
<script src="https://raw.githubusercontent.com/blueimp/JavaScript-Load-Image/master/js/load-image.all.min.js"></script>
<p><div id="originalPicture" style="width: 100%"></div></p>
```
```javascript
let options = {
x: 0,
y: 0,
width: window.screen.width,
height: window.screen.height,
camera: CameraPreview.CAMERA_DIRECTION.BACK,
toBack: false,
tapPhoto: true,
tapFocus: false,
previewDrag: false,
disableExifHeaderStripping: true,
storeToFile: true
};
....
function gotRotatedCanvas(canvasimg) {
var displayCanvas = $('canvas#display-canvas');
loadImage.scale(canvasimg, function(img){
displayCanvas.drawImage(img)
}, {
maxWidth: displayCanvas.width,
maxHeight: displayCanvas.height
});
var opt = {
cameraDirection: CameraPreview.CAMERA_DIRECTION.BACK,
width: (window.screen.width / 2),
height: (window.screen.height / 2),
quality: 60,
withFlash: false
}
CameraPreview.getSupportedPictureSizes(function(dimensions){
dimensions.sort(function(a, b){
return (b.width * b.height - a.width * a.height);
});
var dimension = dimensions[0];
CameraPreview.takePicture({width:dimension.width, height:dimension.height, quality: 85}, function(path){
var image = 'file://' + path;
let holder = document.getElementById('originalPicture');
let width = holder.offsetWidth;
loadImage(
image,
function(canvas) {
holder.innerHTML = "";
if (app.camera === 'front') {
// front camera requires we flip horizontally
canvas.style.transform = 'scale(1, -1)';
}
holder.appendChild(canvas);
},
{
maxWidth: width,
orientation: true,
canvas: true
}
);
});
CameraPreview.startRecordVideo(opts, function(filePath){
console.log(filePath)
});
```
## disableExifHeaderStripping
### stopRecordVideo(cb, [errorCallback])
If you want to capture large images you will notice in Android that performace is very bad, in those cases you can set
this flag, and add some extra Javascript/HTML to get a proper display of your captured images without risking your application speed.
*Currently this feature is for Android only. A PR for iOS support would be happily accepted*
Example:
<info>Stop recording video and return video file path</info><br/>
```html
<script src="https://raw.githubusercontent.com/blueimp/JavaScript-Load-Image/master/js/load-image.all.min.js"></script>
<p><div id="originalPicture" style="width: 100%"></div></p>
```
```javascript
let options = {
x: 0,
y: 0,
width: window.screen.width,
height: window.screen.height,
camera: CameraPreview.CAMERA_DIRECTION.BACK,
toBack: false,
tapPhoto: true,
tapFocus: false,
previewDrag: false,
disableExifHeaderStripping: true
};
....
function gotRotatedCanvas(canvasimg) {
var displayCanvas = $('canvas#display-canvas');
loadImage.scale(canvasimg, function(img){
displayCanvas.drawImage(img)
}, {
maxWidth: displayCanvas.width,
maxHeight: displayCanvas.height
});
}
CameraPreview.getSupportedPictureSizes(function(dimensions){
dimensions.sort(function(a, b){
return (b.width * b.height - a.width * a.height);
});
var dimension = dimensions[0];
CameraPreview.takePicture({width:dimension.width, height:dimension.height, quality: 85}, function(base64PictureData){
/*
base64PictureData is base64 encoded jpeg image. Use this data to store to a file or upload.
Its up to the you to figure out the best way to save it to disk or whatever for your application.
*/
var image = 'data:image/jpeg;base64,' + imgData;
let holder = document.getElementById('originalPicture');
let width = holder.offsetWidth;
loadImage(
image,
function(canvas) {
holder.innerHTML = "";
if (app.camera === 'front') {
// front camera requires we flip horizontally
canvas.style.transform = 'scale(1, -1)';
}
holder.appendChild(canvas);
},
{
maxWidth: width,
orientation: true,
canvas: true
}
);
});
CameraPreview.stopRecordVideo(function(filePath) {
console.log(filePath);
});
```

@@ -774,17 +666,2 @@

# IOS Quirks
It is not possible to use your computers webcam during testing in the simulator, you must device test.
# Customize Android Support Library versions (Android only)
The default `ANDROID_SUPPORT_LIBRARY_VERSION` is set to `26+`.
If you need a different version, add argument `--variable ANDROID_SUPPORT_LIBRARY_VERSION="{version}"`.
Or edit `config.xml` with following,
```xml
<plugin name="cordova-plugin-camera-preview" spec="X.X.X">
<variable name="ANDROID_SUPPORT_LIBRARY_VERSION" value="26+" />
</plugin>
```
# Sample App

@@ -791,0 +668,0 @@

@@ -10,2 +10,3 @@ package com.cordovaplugincamerapreview;

import android.graphics.Bitmap.CompressFormat;
import android.media.AudioManager;
import android.util.Base64;

@@ -21,5 +22,8 @@ import android.graphics.BitmapFactory;

import android.hardware.Camera.ShutterCallback;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.util.Log;
import android.util.DisplayMetrics;
import android.util.Size;
import android.view.GestureDetector;

@@ -38,3 +42,3 @@ import android.view.Gravity;

import android.widget.RelativeLayout;
import android.support.media.ExifInterface;
import androidx.exifinterface.media.ExifInterface;

@@ -67,2 +71,6 @@ import org.apache.cordova.LOG;

void onCameraStarted();
void onStartRecordVideo();
void onStartRecordVideoError(String message);
void onStopRecordVideo(String file);
void onStopRecordVideoError(String error);
}

@@ -88,2 +96,3 @@

public String defaultCamera;
public boolean tapToTakePicture;

@@ -101,2 +110,8 @@ public boolean dragEnabled;

private enum RecordingState {INITIALIZING, STARTED, STOPPED}
private RecordingState mRecordingState = RecordingState.INITIALIZING;
private MediaRecorder mRecorder = null;
private String recordFilePath;
public void setEventListener(CameraPreviewListener listener){

@@ -148,110 +163,109 @@ eventListener = listener;

}
private void setupTouchAndBackButton() {
final GestureDetector gestureDetector = new GestureDetector(getActivity().getApplicationContext(), new TapGestureDetector());
private void setupTouchAndBackButton(){
final GestureDetector gestureDetector = new GestureDetector(getActivity().getApplicationContext(), new TapGestureDetector());
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
frameContainerLayout.setClickable(true);
frameContainerLayout.setOnTouchListener(new View.OnTouchListener() {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
frameContainerLayout.setClickable(true);
frameContainerLayout.setOnTouchListener(new View.OnTouchListener() {
private int mLastTouchX;
private int mLastTouchY;
private int mPosX = 0;
private int mPosY = 0;
private int mLastTouchX;
private int mLastTouchY;
private int mPosX = 0;
private int mPosY = 0;
@Override
public boolean onTouch(View v, MotionEvent event) {
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) frameContainerLayout.getLayoutParams();
@Override
public boolean onTouch(View v, MotionEvent event) {
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) frameContainerLayout.getLayoutParams();
boolean isSingleTapTouch = gestureDetector.onTouchEvent(event);
if (event.getAction() != MotionEvent.ACTION_MOVE && isSingleTapTouch) {
if (tapToTakePicture && tapToFocus) {
setFocusArea((int) event.getX(0), (int) event.getY(0), new Camera.AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
if (success) {
takePicture(0, 0, 85);
} else {
Log.d(TAG, "onTouch:" + " setFocusArea() did not suceed");
}
boolean isSingleTapTouch = gestureDetector.onTouchEvent(event);
if (event.getAction() != MotionEvent.ACTION_MOVE && isSingleTapTouch) {
if (tapToTakePicture && tapToFocus) {
setFocusArea((int) event.getX(0), (int) event.getY(0), new Camera.AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
if (success) {
takePicture(0, 0, 85);
} else {
Log.d(TAG, "onTouch:" + " setFocusArea() did not suceed");
}
});
}
});
} else if (tapToTakePicture) {
takePicture(0, 0, 85);
} else if (tapToTakePicture) {
takePicture(0, 0, 85);
} else if (tapToFocus) {
setFocusArea((int) event.getX(0), (int) event.getY(0), new Camera.AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
if (success) {
// A callback to JS might make sense here.
} else {
Log.d(TAG, "onTouch:" + " setFocusArea() did not suceed");
}
} else if (tapToFocus) {
setFocusArea((int) event.getX(0), (int) event.getY(0), new Camera.AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
if (success) {
// A callback to JS might make sense here.
} else {
Log.d(TAG, "onTouch:" + " setFocusArea() did not suceed");
}
});
}
return true;
} else {
if (dragEnabled) {
int x;
int y;
}
});
}
return true;
} else {
if (dragEnabled) {
int x;
int y;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (mLastTouchX == 0 || mLastTouchY == 0) {
mLastTouchX = (int) event.getRawX() - layoutParams.leftMargin;
mLastTouchY = (int) event.getRawY() - layoutParams.topMargin;
} else {
mLastTouchX = (int) event.getRawX();
mLastTouchY = (int) event.getRawY();
}
break;
case MotionEvent.ACTION_MOVE:
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (mLastTouchX == 0 || mLastTouchY == 0) {
mLastTouchX = (int) event.getRawX() - layoutParams.leftMargin;
mLastTouchY = (int) event.getRawY() - layoutParams.topMargin;
} else {
mLastTouchX = (int) event.getRawX();
mLastTouchY = (int) event.getRawY();
}
break;
case MotionEvent.ACTION_MOVE:
x = (int) event.getRawX();
y = (int) event.getRawY();
x = (int) event.getRawX();
y = (int) event.getRawY();
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
mPosX += dx;
mPosY += dy;
mPosX += dx;
mPosY += dy;
layoutParams.leftMargin = mPosX;
layoutParams.topMargin = mPosY;
layoutParams.leftMargin = mPosX;
layoutParams.topMargin = mPosY;
frameContainerLayout.setLayoutParams(layoutParams);
frameContainerLayout.setLayoutParams(layoutParams);
// Remember this touch position for the next move event
mLastTouchX = x;
mLastTouchY = y;
// Remember this touch position for the next move event
mLastTouchX = x;
mLastTouchY = y;
break;
default:
break;
}
break;
default:
break;
}
}
return true;
}
});
frameContainerLayout.setFocusableInTouchMode(true);
frameContainerLayout.requestFocus();
frameContainerLayout.setOnKeyListener(new android.view.View.OnKeyListener() {
@Override
public boolean onKey(android.view.View v, int keyCode, android.view.KeyEvent event) {
return true;
}
});
if (keyCode == android.view.KeyEvent.KEYCODE_BACK) {
eventListener.onBackButton();
return true;
}
return false;
frameContainerLayout.setFocusableInTouchMode(true);
frameContainerLayout.requestFocus();
frameContainerLayout.setOnKeyListener(new android.view.View.OnKeyListener() {
@Override
public boolean onKey(android.view.View v, int keyCode, android.view.KeyEvent event) {
if (keyCode == android.view.KeyEvent.KEYCODE_BACK) {
eventListener.onBackButton();
return true;
}
});
}
});
return false;
}
});
}
});
}

@@ -333,2 +347,5 @@

}
Activity activity = getActivity();
muteStream(false, activity);
}

@@ -343,3 +360,3 @@

numberOfCameras = Camera.getNumberOfCameras();
// check for availability of multiple cameras

@@ -567,7 +584,4 @@ if (numberOfCameras == 1) {

}
static byte[] rotateNV21(final byte[] yuv,
final int width,
final int height,
final int rotation)
{
static byte[] rotateNV21(final byte[] yuv, final int width, final int height, final int rotation){
if (rotation == 0) return yuv;

@@ -608,2 +622,3 @@ if (rotation % 90 != 0 || rotation < 0 || rotation > 270) {

}
public void takeSnapshot(final int quality) {

@@ -679,5 +694,129 @@ mCamera.setPreviewCallback(new Camera.PreviewCallback() {

public void startRecord(final String filePath, final String camera, final int width, final int height, final int quality, final boolean withFlash){
Log.d(TAG, "CameraPreview startRecord camera: " + camera + " width: " + width + ", height: " + height + ", quality: " + quality);
Activity activity = getActivity();
muteStream(true, activity);
if (this.mRecordingState == RecordingState.STARTED) {
Log.d(TAG, "Already Recording");
return;
}
this.recordFilePath = filePath;
int mOrientationHint = calculateOrientationHint();
int videoWidth = 0;//set whatever
int videoHeight = 0;//set whatever
Camera.Parameters cameraParams = mCamera.getParameters();
if (withFlash) {
cameraParams.setFlashMode(withFlash ? Camera.Parameters.FLASH_MODE_TORCH : Camera.Parameters.FLASH_MODE_OFF);
mCamera.setParameters(cameraParams);
mCamera.startPreview();
}
mCamera.unlock();
mRecorder = new MediaRecorder();
try {
mRecorder.setCamera(mCamera);
CamcorderProfile profile;
if (CamcorderProfile.hasProfile(defaultCameraId, CamcorderProfile.QUALITY_HIGH)) {
profile = CamcorderProfile.get(defaultCameraId, CamcorderProfile.QUALITY_HIGH);
} else {
if (CamcorderProfile.hasProfile(defaultCameraId, CamcorderProfile.QUALITY_480P)) {
profile = CamcorderProfile.get(defaultCameraId, CamcorderProfile.QUALITY_480P);
} else {
if (CamcorderProfile.hasProfile(defaultCameraId, CamcorderProfile.QUALITY_720P)) {
profile = CamcorderProfile.get(defaultCameraId, CamcorderProfile.QUALITY_720P);
} else {
if (CamcorderProfile.hasProfile(defaultCameraId, CamcorderProfile.QUALITY_1080P)) {
profile = CamcorderProfile.get(defaultCameraId, CamcorderProfile.QUALITY_1080P);
} else {
profile = CamcorderProfile.get(defaultCameraId, CamcorderProfile.QUALITY_LOW);
}
}
}
}
mRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_RECOGNITION);
mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mRecorder.setProfile(profile);
mRecorder.setOutputFile(filePath);
mRecorder.setOrientationHint(mOrientationHint);
mRecorder.prepare();
Log.d(TAG, "Starting recording");
mRecorder.start();
eventListener.onStartRecordVideo();
} catch (IOException e) {
eventListener.onStartRecordVideoError(e.getMessage());
}
}
public int calculateOrientationHint() {
DisplayMetrics dm = new DisplayMetrics();
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(defaultCameraId, info);
int cameraRotationOffset = info.orientation;
Activity activity = getActivity();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
int currentScreenRotation = activity.getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch (currentScreenRotation) {
case Surface.ROTATION_0:
degrees = 0;
break;
case Surface.ROTATION_90:
degrees = 90;
break;
case Surface.ROTATION_180:
degrees = 180;
break;
case Surface.ROTATION_270:
degrees = 270;
break;
}
int orientation;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
orientation = (cameraRotationOffset + degrees) % 360;
if (degrees != 0) {
orientation = (360 - orientation) % 360;
}
} else {
orientation = (cameraRotationOffset - degrees + 360) % 360;
}
Log.w(TAG, "************orientationHint ***********= " + orientation);
return orientation;
}
public void stopRecord() {
Log.d(TAG, "stopRecord");
try {
mRecorder.stop();
mRecorder.reset(); // clear recorder configuration
mRecorder.release(); // release the recorder object
mRecorder = null;
mCamera.lock();
Camera.Parameters cameraParams = mCamera.getParameters();
cameraParams.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
mCamera.setParameters(cameraParams);
mCamera.startPreview();
eventListener.onStopRecordVideo(this.recordFilePath);
} catch (Exception e) {
eventListener.onStopRecordVideoError(e.getMessage());
}
}
public void muteStream(boolean mute, Activity activity) {
AudioManager audioManager = ((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE));
int direction = mute ? audioManager.ADJUST_MUTE : audioManager.ADJUST_UNMUTE;
}
public void setFocusArea(final int pointX, final int pointY, final Camera.AutoFocusCallback callback) {
if (mCamera != null) {
mCamera.cancelAutoFocus();

@@ -726,2 +865,19 @@

}
static Camera.Size getBestResolution(Camera.Parameters cp) {
List<Camera.Size> sl = cp.getSupportedVideoSizes();
if (sl == null)
sl = cp.getSupportedPictureSizes();
Camera.Size large = sl.get(0);
for (Camera.Size s : sl) {
if ((large.height * large.width) < (s.height * s.width)) {
large = s;
}
}
return large;
}
}
package com.cordovaplugincamerapreview;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.PackageManager;

@@ -9,2 +11,3 @@ import android.app.FragmentManager;

import android.hardware.Camera;
import android.os.Handler;
import android.hardware.camera2.CameraAccessException;

@@ -30,2 +33,3 @@ import android.hardware.camera2.CameraCharacteristics;

import java.io.File;
import java.util.List;

@@ -52,2 +56,4 @@ import java.util.Arrays;

private static final String TAKE_PICTURE_ACTION = "takePicture";
private static final String START_RECORD_VIDEO_ACTION = "startRecordVideo";
private static final String STOP_RECORD_VIDEO_ACTION = "stopRecordVideo";
private static final String TAKE_SNAPSHOT_ACTION = "takeSnapshot";

@@ -74,2 +80,5 @@ private static final String SHOW_CAMERA_ACTION = "showCamera";

private static final int CAM_REQ_CODE = 0;
private static final int VID_REQ_CODE = 1;
private String VIDEO_FILE_PATH = "";
private static final String VIDEO_FILE_EXTENSION = ".mp4";

@@ -80,5 +89,12 @@ private static final String [] permissions = {

private static final String [] videoPermissions = {
Manifest.permission.RECORD_AUDIO,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
private CameraActivity fragment;
private CallbackContext takePictureCallbackContext;
private CallbackContext takeSnapshotCallbackContext;
private CallbackContext startRecordVideoCallbackContext;
private CallbackContext stopRecordVideoCallbackContext;
private CallbackContext setFocusCallbackContext;

@@ -115,2 +131,13 @@ private CallbackContext startCameraCallbackContext;

return takeSnapshot(args.getInt(0), callbackContext);
}else if (START_RECORD_VIDEO_ACTION.equals(action)) {
if ( cordova.hasPermission(videoPermissions[0]) && cordova.hasPermission(videoPermissions[1])) {
return startRecordVideo(args.getString(0), args.getInt(1), args.getInt(2), args.getInt(3), args.getBoolean(4), callbackContext);
} else {
this.execCallback = callbackContext;
this.execArgs = args;
cordova.requestPermissions(this, VID_REQ_CODE, videoPermissions);
return true;
}
} else if (STOP_RECORD_VIDEO_ACTION.equals(action)) {
return stopRecordVideo(callbackContext);
} else if (COLOR_EFFECT_ACTION.equals(action)) {

@@ -176,3 +203,4 @@ return setColorEffect(args.getString(0), callbackContext);

return getCameraCharacteristics(callbackContext);
}
}
return false;

@@ -189,4 +217,7 @@ }

}
if (requestCode == CAM_REQ_CODE) {
if(requestCode == CAM_REQ_CODE){
startCamera(this.execArgs.getInt(0), this.execArgs.getInt(1), this.execArgs.getInt(2), this.execArgs.getInt(3), this.execArgs.getString(4), this.execArgs.getBoolean(5), this.execArgs.getBoolean(6), this.execArgs.getBoolean(7), this.execArgs.getString(8), this.execArgs.getBoolean(9), this.execArgs.getBoolean(10), this.execArgs.getBoolean(11), this.execCallback);
}else if(requestCode == VID_REQ_CODE){
startRecordVideo(this.execArgs.getString(0), this.execArgs.getInt(1), this.execArgs.getInt(2), this.execArgs.getInt(3), this.execArgs.getBoolean(4), this.execCallback);
}

@@ -248,4 +279,5 @@ }

private boolean startCamera(int x, int y, int width, int height, String defaultCamera, Boolean tapToTakePicture, Boolean dragEnabled, final Boolean toBack, String alpha, boolean tapFocus, boolean disableExifHeaderStripping, boolean storeToFile, CallbackContext callbackContext) {
private boolean startCamera(int x, int y, int width, int height, String defaultCamera, Boolean tapToTakePicture, Boolean dragEnabled, final Boolean toBack, String alpha, boolean tapFocus, boolean disableExifHeaderStripping, boolean storeToFile, CallbackContext callbackContext) {
Log.d(TAG, "start camera action");
if (fragment != null) {

@@ -269,2 +301,3 @@ callbackContext.error("Camera already started");

DisplayMetrics metrics = cordova.getActivity().getResources().getDisplayMetrics();
// offset

@@ -286,3 +319,2 @@ int computedX = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, x, metrics);

//create or update the layout params for the container view

@@ -297,5 +329,5 @@ FrameLayout containerView = (FrameLayout)cordova.getActivity().findViewById(containerViewId);

}
//display camera bellow the webview
//display camera below the webview
if(toBack){
View view = webView.getView();

@@ -306,2 +338,3 @@ ViewParent rootParent = containerView.getParent();

view.setBackgroundColor(0x00000000);
// If parents do not match look for.

@@ -329,7 +362,5 @@ if(curParent.getParent() != rootParent) {

}else{
//set camera back to front
containerView.setAlpha(opacity);
containerView.bringToFront();
}

@@ -352,3 +383,3 @@

PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, "Camera started");
pluginResult.setKeepCallback(true);
pluginResult.setKeepCallback(false);
startCameraCallbackContext.sendPluginResult(pluginResult);

@@ -390,3 +421,2 @@ }

}
takePictureCallbackContext = callbackContext;

@@ -406,3 +436,3 @@

PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, data);
pluginResult.setKeepCallback(true);
pluginResult.setKeepCallback(fragment.tapToTakePicture);
takePictureCallbackContext.sendPluginResult(pluginResult);

@@ -416,2 +446,80 @@ }

private boolean startRecordVideo(String camera, int width, int height, int quality, boolean withFlash, CallbackContext callbackContext) {
if(this.hasView(callbackContext) == false){
return true;
}
final String filename = "videoTmp";
VIDEO_FILE_PATH = cordova.getActivity().getCacheDir().toString() + "/";
startRecordVideoCallbackContext = callbackContext;
cordova.getThreadPool().execute(new Runnable() {
@Override
public void run() {
fragment.startRecord(getFilePath(filename), camera, width, height, quality, withFlash);
}
});
return true;
}
public void onStartRecordVideo() {
Log.d(TAG, "onStartRecordVideo started");
PluginResult pluginResult = new PluginResult(PluginResult.Status.OK);
pluginResult.setKeepCallback(true);
startRecordVideoCallbackContext.sendPluginResult(pluginResult);
}
public void onStartRecordVideoError(String message) {
Log.d(TAG, "CameraPreview onStartRecordVideo");
startRecordVideoCallbackContext.error(message);
}
private boolean stopRecordVideo(CallbackContext callbackContext) {
if(this.hasView(callbackContext) == false){
return true;
}
stopRecordVideoCallbackContext = callbackContext;
cordova.getThreadPool().execute(new Runnable() {
@Override
public void run() {
fragment.stopRecord();
}
});
return true;
}
public void onStopRecordVideo(String file) {
Log.d(TAG, "onStopRecordVideo success");
PluginResult result = new PluginResult(PluginResult.Status.OK, file);
result.setKeepCallback(true);
stopRecordVideoCallbackContext.sendPluginResult(result);
}
public void onStopRecordVideoError(String err) {
Log.d(TAG, "onStopRecordVideo error");
stopRecordVideoCallbackContext.error(err);
}
private String getFilePath(String filename) {
String fileName = filename;
int i = 1;
while (new File(VIDEO_FILE_PATH + fileName + VIDEO_FILE_EXTENSION).exists()) {
// Add number suffix if file exists
fileName = filename + '_' + i;
i++;
}
return VIDEO_FILE_PATH + fileName + VIDEO_FILE_EXTENSION;
}
private boolean setColorEffect(String effect, CallbackContext callbackContext) {

@@ -440,22 +548,23 @@ if(this.hasCamera(callbackContext) == false){

private boolean getSupportedColorEffects(CallbackContext callbackContext) {
if(this.hasCamera(callbackContext) == false){
return true;
}
if(this.hasCamera(callbackContext) == false){
return true;
}
Camera camera = fragment.getCamera();
Camera.Parameters params = camera.getParameters();
List<String> supportedColors;
supportedColors = params.getSupportedColorEffects();
JSONArray jsonColorEffects = new JSONArray();
Camera camera = fragment.getCamera();
Camera.Parameters params = camera.getParameters();
List<String> supportedColors;
supportedColors = params.getSupportedColorEffects();
JSONArray jsonColorEffects = new JSONArray();
if (supportedColors != null) {
for (int i=0; i<supportedColors.size(); i++) {
jsonColorEffects.put(new String(supportedColors.get(i)));
}
if (supportedColors != null) {
for (int i=0; i<supportedColors.size(); i++) {
jsonColorEffects.put(new String(supportedColors.get(i)));
}
callbackContext.success(jsonColorEffects);
return true;
}
callbackContext.success(jsonColorEffects);
return true;
}
private boolean getExposureModes(CallbackContext callbackContext) {

@@ -477,2 +586,3 @@ if(this.hasCamera(callbackContext) == false){

}
return true;

@@ -501,2 +611,3 @@ }

}
return true;

@@ -520,2 +631,3 @@ }

}
return true;

@@ -538,2 +650,3 @@ }

}
return true;

@@ -566,3 +679,4 @@ }

}
return true;
return true;
}

@@ -594,2 +708,3 @@

}
return true;

@@ -618,2 +733,3 @@ }

}
callbackContext.success(jsonWhiteBalanceModes);

@@ -647,2 +763,3 @@ return true;

}
return true;

@@ -681,2 +798,3 @@ }

}
return true;

@@ -699,2 +817,3 @@ }

}
return true;

@@ -708,10 +827,9 @@ }

Camera camera = fragment.getCamera();
Camera.Parameters params = camera.getParameters();
Camera camera = fragment.getCamera();
Camera.Parameters params = camera.getParameters();
float horizontalViewAngle = params.getHorizontalViewAngle();
float horizontalViewAngle = params.getHorizontalViewAngle();
callbackContext.success(String.valueOf(horizontalViewAngle));
return true;
callbackContext.success(String.valueOf(horizontalViewAngle));
return true;
}

@@ -734,2 +852,3 @@

}
return true;

@@ -774,3 +893,3 @@ }

private boolean getSupportedFlashModes(CallbackContext callbackContext) {
private boolean getSupportedFlashModes(CallbackContext callbackContext) {
if(this.hasCamera(callbackContext) == false){

@@ -796,3 +915,3 @@ return true;

private boolean getSupportedFocusModes(CallbackContext callbackContext) {
private boolean getSupportedFocusModes(CallbackContext callbackContext) {
if(this.hasCamera(callbackContext) == false){

@@ -812,5 +931,7 @@ return true;

}
callbackContext.success(jsonFocusModes);
return true;
}
callbackContext.error("Camera focus modes parameters access error");

@@ -837,6 +958,7 @@ return true;

}
return true;
}
private boolean setFocusMode(String focusMode, CallbackContext callbackContext) {
private boolean setFocusMode(String focusMode, CallbackContext callbackContext) {
if(this.hasCamera(callbackContext) == false){

@@ -878,2 +1000,3 @@ return true;

}
return true;

@@ -906,3 +1029,2 @@ }

private boolean stopCamera(CallbackContext callbackContext) {
if(webViewParent != null) {

@@ -976,2 +1098,3 @@ cordova.getActivity().runOnUiThread(new Runnable() {

});
return true;

@@ -1009,2 +1132,3 @@ }

callbackContext.success();
return true;

@@ -1022,3 +1146,5 @@ }

}
Log.d(TAG, "Back button tapped, notifying");
PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, "Back button pressed");

@@ -1035,20 +1161,20 @@ tapBackButtonContext.sendPluginResult(pluginResult);

JSONArray cameraCharacteristicsArray = new JSONArray();
// Get the CameraManager
CameraManager cManager = (CameraManager) this.cordova.getActivity().getApplicationContext().getSystemService(Context.CAMERA_SERVICE);
try {
for (String cameraId : cManager.getCameraIdList()) {
CameraCharacteristics characteristics = cManager.getCameraCharacteristics(cameraId);
JSONObject cameraData = new JSONObject();
// INFO_SUPPORTED_HARDWARE_LEVEL
Integer supportLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
cameraData.put("INFO_SUPPORTED_HARDWARE_LEVEL", supportLevel);
// LENS_FACING
Integer lensFacing = characteristics.get(CameraCharacteristics.LENS_FACING);
cameraData.put("LENS_FACING", lensFacing);
// SENSOR_INFO_PHYSICAL_SIZE

@@ -1058,3 +1184,3 @@ SizeF sensorInfoPhysicalSize = characteristics.get(CameraCharacteristics.SENSOR_INFO_PHYSICAL_SIZE);

cameraData.put("SENSOR_INFO_PHYSICAL_SIZE_HEIGHT", new Double(sensorInfoPhysicalSize.getHeight()));
// SENSOR_INFO_PIXEL_ARRAY_SIZE

@@ -1064,3 +1190,3 @@ Size sensorInfoPixelSize = characteristics.get(CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE);

cameraData.put("SENSOR_INFO_PIXEL_ARRAY_SIZE_HEIGHT", new Integer(sensorInfoPixelSize.getHeight()));
// LENS_INFO_AVAILABLE_FOCAL_LENGTHS

@@ -1075,9 +1201,9 @@ float[] focalLengths = characteristics.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS);

cameraData.put("LENS_INFO_AVAILABLE_FOCAL_LENGTHS", focalLengthsArray);
// add camera data to result list
cameraCharacteristicsArray.put(cameraData);
}
data.put("CAMERA_CHARACTERISTICS", cameraCharacteristicsArray);
} catch (CameraAccessException e) {

@@ -1092,3 +1218,3 @@ Log.e(TAG, e.getMessage(), e);

}
}

@@ -51,5 +51,6 @@ package com.cordovaplugincamerapreview;

public void setCamera(Camera camera, int cameraId) {
mCamera = camera;
this.cameraId = cameraId;
if (camera != null) {
mCamera = camera;
this.cameraId = cameraId;
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();

@@ -56,0 +57,0 @@ setCameraDisplayOrientation();

@@ -87,10 +87,10 @@ #import <Cordova/CDV.h>

CDVPluginResult *pluginResult;
if(self.sessionManager != nil) {
[self.cameraRenderController.view removeFromSuperview];
[self.cameraRenderController removeFromParentViewController];
self.cameraRenderController = nil;
self.sessionManager = nil;
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];

@@ -101,3 +101,3 @@ }

}
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];

@@ -748,7 +748,7 @@ }

NSError *err;
if (![data writeToFile:filePath options:NSAtomicWrite error:&err]) {
if (![data writeToFile:filePath options:NSAtomicWrite error:&err]) {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[err localizedDescription]];
}
else {
else {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:[[NSURL fileURLWithPath:filePath] absoluteString]];

@@ -765,3 +765,3 @@ }

[pluginResult setKeepCallbackAsBool:true];
[pluginResult setKeepCallbackAsBool:self.cameraRenderController.tapToTakePicture];
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.onPictureTakenHandlerId];

@@ -789,3 +789,3 @@ }

} while ([fileMgr fileExistsAtPath:filePath]);
return filePath;

@@ -792,0 +792,0 @@ }

@@ -54,3 +54,2 @@ #import <CoreImage/CoreImage.h>

@property (nonatomic) NSDictionary *colorTemperatures;
@end

@@ -13,67 +13,69 @@ declare module 'cordova-plugin-camera-preview' {

interface CameraPreviewStartCameraOptions {
alpha?: number;
camera?: CameraPreviewCameraDirection|string;
height?: number;
previewDrag?: boolean;
tapFocus?: boolean;
tapPhoto?: boolean;
toBack?: boolean;
width?: number;
x?: number;
y?: number;
disableExifHeaderStripping?: boolean;
storeToFile?: boolean;
alpha?: number;
camera?: CameraPreviewCameraDirection|string;
height?: number;
previewDrag?: boolean;
tapFocus?: boolean;
tapPhoto?: boolean;
toBack?: boolean;
width?: number;
x?: number;
y?: number;
disableExifHeaderStripping?: boolean;
storeToFile?: boolean;
}
interface CameraPreviewTakePictureOptions {
height?: number;
quality?: number;
width?: number;
height?: number;
quality?: number;
width?: number;
}
interface CameraPreviewTakeSnapshotOptions {
quality?: number;
quality?: number;
}
interface CameraPreviewPreviewSizeDimension {
height?: number;
width?: number;
height?: number;
width?: number;
}
interface CameraPreview {
startCamera(options?: CameraPreviewStartCameraOptions, onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
stopCamera(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
switchCamera(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
hide(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
show(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
takePicture(options?: CameraPreviewTakePictureOptions|CameraPreviewSuccessHandler, onSuccess?: CameraPreviewSuccessHandler|CameraPreviewErrorHandler, onError?: CameraPreviewErrorHandler): void;
takeSnapshot(options?: CameraPreviewTakeSnapshotOptions|CameraPreviewSuccessHandler, onSuccess?: CameraPreviewSuccessHandler|CameraPreviewErrorHandler, onError?: CameraPreviewErrorHandler): void;
setColorEffect(effect: CameraPreviewColorEffect|string, onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
setZoom(zoom?: number, onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getMaxZoom(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getSupportedFocusMode(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getZoom(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getHorizontalFOV(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
setPreviewSize(dimensions?: CameraPreviewPreviewSizeDimension|string, onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getSupportedPictureSizes(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getSupportedFlashModes(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getSupportedColorEffects(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
setFlashMode(flashMode: CameraPreviewFlashMode|string, onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getSupportedFocusModes(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getFocusMode(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
setFocusMode(focusMode?: CameraPreviewFocusMode|string, onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
tapToFocus(xPoint?: number, yPoint?: number, onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getExposureModes(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getExposureMode(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
setExposureMode(exposureMode?: CameraPreviewExposureMode, onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getExposureCompensation(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
setExposureCompensation(exposureCompensation?: number, onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getExposureCompensationRange(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getSupportedWhiteBalanceModes(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getSupportedWhiteBalanceMode(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
setWhiteBalanceMode(whiteBalanceMode?: CameraPreviewWhiteBalanceMode|string, onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
onBackButton(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getBlob(path: string, onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getCameraCharacteristics(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
startCamera(options?: CameraPreviewStartCameraOptions, onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
stopCamera(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
switchCamera(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
hide(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
show(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
takePicture(options?: CameraPreviewTakePictureOptions|CameraPreviewSuccessHandler, onSuccess?: CameraPreviewSuccessHandler|CameraPreviewErrorHandler, onError?: CameraPreviewErrorHandler): void;
takeSnapshot(options?: CameraPreviewTakeSnapshotOptions|CameraPreviewSuccessHandler, onSuccess?: CameraPreviewSuccessHandler|CameraPreviewErrorHandler, onError?: CameraPreviewErrorHandler): void;
setColorEffect(effect: CameraPreviewColorEffect|string, onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
setZoom(zoom?: number, onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
startRecordVideo(options?:any|CameraPreviewSuccessHandler, onSuccess?:CameraPreviewSuccessHandler|CameraPreviewErrorHandler, onError?:CameraPreviewErrorHandler):void;
stopRecordVideo(CameraPreviewSuccessHandler, onSuccess?:CameraPreviewSuccessHandler|CameraPreviewErrorHandler, onError?:CameraPreviewErrorHandler):void;
getMaxZoom(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getSupportedFocusMode(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getZoom(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getHorizontalFOV(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
setPreviewSize(dimensions?: CameraPreviewPreviewSizeDimension|string, onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getSupportedPictureSizes(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getSupportedFlashModes(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getSupportedColorEffects(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
setFlashMode(flashMode: CameraPreviewFlashMode|string, onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getSupportedFocusModes(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getFocusMode(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
setFocusMode(focusMode?: CameraPreviewFocusMode|string, onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
tapToFocus(xPoint?: number, yPoint?: number, onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getExposureModes(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getExposureMode(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
setExposureMode(exposureMode?: CameraPreviewExposureMode, onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getExposureCompensation(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
setExposureCompensation(exposureCompensation?: number, onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getExposureCompensationRange(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getSupportedWhiteBalanceModes(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getSupportedWhiteBalanceMode(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
setWhiteBalanceMode(whiteBalanceMode?: CameraPreviewWhiteBalanceMode|string, onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
onBackButton(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getBlob(path: string, onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
getCameraCharacteristics(onSuccess?: CameraPreviewSuccessHandler, onError?: CameraPreviewErrorHandler): void;
}
}

@@ -10,281 +10,328 @@ var argscheck = require('cordova/argscheck'),

function isFunction(obj) {
return !!(obj && obj.constructor && obj.call && obj.apply);
return !!(obj && obj.constructor && obj.call && obj.apply);
};
CameraPreview.startCamera = function(options, onSuccess, onError) {
if(!options){
options = {};
}else if(isFunction(options)){
onSuccess = options;
options = {};
}
options.x = options.x || 0;
options.y = options.y || 0;
options.width = options.width || window.screen.width;
options.height = options.height || window.screen.height;
options.camera = options.camera || CameraPreview.CAMERA_DIRECTION.FRONT;
if (typeof(options.tapPhoto) === 'undefined') {
options.tapPhoto = true;
}
if (!options) {
options = {};
} else if (isFunction(options)) {
onSuccess = options;
options = {};
}
if (typeof (options.tapFocus) == 'undefined') {
options.tapFocus = false;
}
options.x = options.x || 0;
options.y = options.y || 0;
options.previewDrag = options.previewDrag || false;
options.toBack = options.toBack || false;
if (typeof(options.alpha) === 'undefined') {
options.alpha = 1;
}
options.disableExifHeaderStripping = options.disableExifHeaderStripping || false;
options.storeToFile = options.storeToFile || false;
exec(onSuccess, onError, PLUGIN_NAME, "startCamera", [options.x, options.y, options.width, options.height, options.camera, options.tapPhoto, options.previewDrag, options.toBack, options.alpha, options.tapFocus, options.disableExifHeaderStripping, options.storeToFile]);
options.width = options.width || window.screen.width;
options.height = options.height || window.screen.height;
options.camera = options.camera || CameraPreview.CAMERA_DIRECTION.FRONT;
if (typeof(options.tapPhoto) === 'undefined') {
options.tapPhoto = true;
}
if (typeof (options.tapFocus) == 'undefined') {
options.tapFocus = false;
}
options.previewDrag = options.previewDrag || false;
options.toBack = options.toBack || false;
if (typeof(options.alpha) === 'undefined') {
options.alpha = 1;
}
options.disableExifHeaderStripping = options.disableExifHeaderStripping || false;
options.storeToFile = options.storeToFile || false;
exec(onSuccess, onError, PLUGIN_NAME, "startCamera", [
options.x,
options.y,
options.width,
options.height,
options.camera,
options.tapPhoto,
options.previewDrag,
options.toBack,
options.alpha,
options.tapFocus,
options.disableExifHeaderStripping,
options.storeToFile
]);
};
CameraPreview.stopCamera = function(onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "stopCamera", []);
exec(onSuccess, onError, PLUGIN_NAME, "stopCamera", []);
};
CameraPreview.switchCamera = function(onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "switchCamera", []);
exec(onSuccess, onError, PLUGIN_NAME, "switchCamera", []);
};
CameraPreview.hide = function(onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "hideCamera", []);
exec(onSuccess, onError, PLUGIN_NAME, "hideCamera", []);
};
CameraPreview.show = function(onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "showCamera", []);
exec(onSuccess, onError, PLUGIN_NAME, "showCamera", []);
};
CameraPreview.takeSnapshot = function(opts, onSuccess, onError) {
if (!opts) {
opts = {};
} else if (isFunction(opts)) {
onSuccess = opts;
opts = {};
}
if (!opts) {
opts = {};
} else if (isFunction(opts)) {
onSuccess = opts;
opts = {};
}
if (!isFunction(onSuccess)) {
return false;
}
if (!isFunction(onSuccess)) {
return false;
}
if (!opts.quality || opts.quality > 100 || opts.quality < 0) {
opts.quality = 85;
}
if (!opts.quality || opts.quality > 100 || opts.quality < 0) {
opts.quality = 85;
}
exec(onSuccess, onError, PLUGIN_NAME, "takeSnapshot", [opts.quality]);
exec(onSuccess, onError, PLUGIN_NAME, "takeSnapshot", [opts.quality]);
};
CameraPreview.takePicture = function(opts, onSuccess, onError) {
if (!opts) {
opts = {};
} else if (isFunction(opts)) {
onSuccess = opts;
opts = {};
}
if (!opts) {
opts = {};
} else if (isFunction(opts)) {
onSuccess = opts;
opts = {};
}
if (!isFunction(onSuccess)) {
return false;
}
if (!isFunction(onSuccess)) {
return false;
}
opts.width = opts.width || 0;
opts.height = opts.height || 0;
opts.width = opts.width || 0;
opts.height = opts.height || 0;
if (!opts.quality || opts.quality > 100 || opts.quality < 0) {
opts.quality = 85;
}
if (!opts.quality || opts.quality > 100 || opts.quality < 0) {
opts.quality = 85;
}
exec(onSuccess, onError, PLUGIN_NAME, "takePicture", [opts.width, opts.height, opts.quality]);
exec(onSuccess, onError, PLUGIN_NAME, "takePicture", [opts.width, opts.height, opts.quality]);
};
CameraPreview.setColorEffect = function(effect, onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "setColorEffect", [effect]);
exec(onSuccess, onError, PLUGIN_NAME, "setColorEffect", [effect]);
};
CameraPreview.setZoom = function(zoom, onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "setZoom", [zoom]);
exec(onSuccess, onError, PLUGIN_NAME, "setZoom", [zoom]);
};
CameraPreview.getMaxZoom = function(onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "getMaxZoom", []);
exec(onSuccess, onError, PLUGIN_NAME, "getMaxZoom", []);
};
CameraPreview.getZoom = function(onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "getZoom", []);
exec(onSuccess, onError, PLUGIN_NAME, "getZoom", []);
};
CameraPreview.getHorizontalFOV = function(onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "getHorizontalFOV", []);
exec(onSuccess, onError, PLUGIN_NAME, "getHorizontalFOV", []);
};
CameraPreview.setPreviewSize = function(dimensions, onSuccess, onError) {
dimensions = dimensions || {};
dimensions.width = dimensions.width || window.screen.width;
dimensions.height = dimensions.height || window.screen.height;
dimensions = dimensions || {};
dimensions.width = dimensions.width || window.screen.width;
dimensions.height = dimensions.height || window.screen.height;
exec(onSuccess, onError, PLUGIN_NAME, "setPreviewSize", [dimensions.width, dimensions.height]);
exec(onSuccess, onError, PLUGIN_NAME, "setPreviewSize", [dimensions.width, dimensions.height]);
};
CameraPreview.getSupportedPictureSizes = function(onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "getSupportedPictureSizes", []);
exec(onSuccess, onError, PLUGIN_NAME, "getSupportedPictureSizes", []);
};
CameraPreview.getSupportedFlashModes = function(onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "getSupportedFlashModes", []);
exec(onSuccess, onError, PLUGIN_NAME, "getSupportedFlashModes", []);
};
CameraPreview.getSupportedColorEffects = function(onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "getSupportedColorEffects", []);
exec(onSuccess, onError, PLUGIN_NAME, "getSupportedColorEffects", []);
};
CameraPreview.setFlashMode = function(flashMode, onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "setFlashMode", [flashMode]);
exec(onSuccess, onError, PLUGIN_NAME, "setFlashMode", [flashMode]);
};
CameraPreview.getFlashMode = function(onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "getFlashMode", []);
exec(onSuccess, onError, PLUGIN_NAME, "getFlashMode", []);
};
CameraPreview.getSupportedFocusModes = function(onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "getSupportedFocusModes", []);
exec(onSuccess, onError, PLUGIN_NAME, "getSupportedFocusModes", []);
};
CameraPreview.getFocusMode = function(onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "getFocusMode", []);
exec(onSuccess, onError, PLUGIN_NAME, "getFocusMode", []);
};
CameraPreview.setFocusMode = function(focusMode, onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "setFocusMode", [focusMode]);
exec(onSuccess, onError, PLUGIN_NAME, "setFocusMode", [focusMode]);
};
CameraPreview.tapToFocus = function(xPoint, yPoint, onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "tapToFocus", [xPoint, yPoint]);
exec(onSuccess, onError, PLUGIN_NAME, "tapToFocus", [xPoint, yPoint]);
};
CameraPreview.getExposureModes = function(onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "getExposureModes", []);
exec(onSuccess, onError, PLUGIN_NAME, "getExposureModes", []);
};
CameraPreview.getExposureMode = function(onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "getExposureMode", []);
exec(onSuccess, onError, PLUGIN_NAME, "getExposureMode", []);
};
CameraPreview.setExposureMode = function(exposureMode, onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "setExposureMode", [exposureMode]);
exec(onSuccess, onError, PLUGIN_NAME, "setExposureMode", [exposureMode]);
};
CameraPreview.getExposureCompensation = function(onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "getExposureCompensation", []);
exec(onSuccess, onError, PLUGIN_NAME, "getExposureCompensation", []);
};
CameraPreview.setExposureCompensation = function(exposureCompensation, onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "setExposureCompensation", [exposureCompensation]);
exec(onSuccess, onError, PLUGIN_NAME, "setExposureCompensation", [exposureCompensation]);
};
CameraPreview.getExposureCompensationRange = function(onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "getExposureCompensationRange", []);
exec(onSuccess, onError, PLUGIN_NAME, "getExposureCompensationRange", []);
};
CameraPreview.getSupportedWhiteBalanceModes = function(onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "getSupportedWhiteBalanceModes", []);
exec(onSuccess, onError, PLUGIN_NAME, "getSupportedWhiteBalanceModes", []);
};
CameraPreview.getWhiteBalanceMode = function(onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "getWhiteBalanceMode", []);
exec(onSuccess, onError, PLUGIN_NAME, "getWhiteBalanceMode", []);
};
CameraPreview.setWhiteBalanceMode = function(whiteBalanceMode, onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "setWhiteBalanceMode", [whiteBalanceMode]);
exec(onSuccess, onError, PLUGIN_NAME, "setWhiteBalanceMode", [whiteBalanceMode]);
};
CameraPreview.getCameraCharacteristics = function(onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "getCameraCharacteristics", []);
};
CameraPreview.onBackButton = function(onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "onBackButton");
exec(onSuccess, onError, PLUGIN_NAME, "onBackButton");
};
CameraPreview.getBlob = function(url, onSuccess, onError) {
var xhr = new XMLHttpRequest
xhr.onload = function() {
if (xhr.status != 0 && (xhr.status < 200 || xhr.status >= 300)) {
if (isFunction(onError)) {
onError('Local request failed');
}
return;
}
var blob = new Blob([xhr.response], {type: "image/jpeg"});
if (isFunction(onSuccess)) {
onSuccess(blob);
}
};
xhr.onerror = function() {
if (isFunction(onError)) {
onError('Local request failed');
}
};
xhr.open('GET', url);
xhr.responseType = 'arraybuffer';
xhr.send(null);
CameraPreview.getBlob = function (url, onSuccess, onError) {
var xhr = new XMLHttpRequest
xhr.onload = function() {
if (xhr.status != 0 && (xhr.status < 200 || xhr.status >= 300)) {
if (isFunction(onError)) {
onError('Local request failed');
}
return;
}
var blob = new Blob([xhr.response], {type: "image/jpeg"});
if (isFunction(onSuccess)) {
onSuccess(blob);
}
};
xhr.onerror = function() {
if (isFunction(onError)) {
onError('Local request failed');
}
};
xhr.open('GET', url);
xhr.responseType = 'arraybuffer';
xhr.send(null);
};
CameraPreview.getCameraCharacteristics = function(onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "getCameraCharacteristics", []);
CameraPreview.startRecordVideo = function (opts, onSuccess, onError) {
if (!opts) {
opts = {};
} else if (isFunction(opts)) {
onSuccess = opts;
opts = {};
}
if (!isFunction(onSuccess)) {
return false;
}
opts.width = opts.width || 0;
opts.height = opts.height || 0;
if (!opts.quality || opts.quality > 100 || opts.quality < 0) {
opts.quality = 85;
}
exec(onSuccess, onError, PLUGIN_NAME, "startRecordVideo", [opts.cameraDirection, opts.width, opts.height, opts.quality, opts.withFlash]);
};
CameraPreview.stopRecordVideo = function (onSuccess, onError) {
exec(onSuccess, onError, PLUGIN_NAME, "stopRecordVideo");
};
CameraPreview.FOCUS_MODE = {
FIXED: 'fixed',
AUTO: 'auto',
CONTINUOUS: 'continuous', // IOS Only
CONTINUOUS_PICTURE: 'continuous-picture', // Android Only
CONTINUOUS_VIDEO: 'continuous-video', // Android Only
EDOF: 'edof', // Android Only
INFINITY: 'infinity', // Android Only
MACRO: 'macro' // Android Only
FIXED: 'fixed',
AUTO: 'auto',
CONTINUOUS: 'continuous', // IOS Only
CONTINUOUS_PICTURE: 'continuous-picture', // Android Only
CONTINUOUS_VIDEO: 'continuous-video', // Android Only
EDOF: 'edof', // Android Only
INFINITY: 'infinity', // Android Only
MACRO: 'macro' // Android Only
};
CameraPreview.EXPOSURE_MODE = {
LOCK: 'lock',
AUTO: 'auto', // IOS Only
CONTINUOUS: 'continuous', // IOS Only
CUSTOM: 'custom' // IOS Only
LOCK: 'lock',
AUTO: 'auto', // IOS Only
CONTINUOUS: 'continuous', // IOS Only
CUSTOM: 'custom' // IOS Only
};
CameraPreview.WHITE_BALANCE_MODE = {
LOCK: 'lock',
AUTO: 'auto',
CONTINUOUS: 'continuous',
INCANDESCENT: 'incandescent',
CLOUDY_DAYLIGHT: 'cloudy-daylight',
DAYLIGHT: 'daylight',
FLUORESCENT: 'fluorescent',
SHADE: 'shade',
TWILIGHT: 'twilight',
WARM_FLUORESCENT: 'warm-fluorescent'
LOCK: 'lock',
AUTO: 'auto',
CONTINUOUS: 'continuous',
INCANDESCENT: 'incandescent',
CLOUDY_DAYLIGHT: 'cloudy-daylight',
DAYLIGHT: 'daylight',
FLUORESCENT: 'fluorescent',
SHADE: 'shade',
TWILIGHT: 'twilight',
WARM_FLUORESCENT: 'warm-fluorescent'
};
CameraPreview.FLASH_MODE = {
OFF: 'off',
ON: 'on',
AUTO: 'auto',
RED_EYE: 'red-eye', // Android Only
TORCH: 'torch'
OFF: 'off',
ON: 'on',
AUTO: 'auto',
RED_EYE: 'red-eye', // Android Only
TORCH: 'torch'
};
CameraPreview.COLOR_EFFECT = {
AQUA: 'aqua', // Android Only
BLACKBOARD: 'blackboard', // Android Only
MONO: 'mono',
NEGATIVE: 'negative',
NONE: 'none',
POSTERIZE: 'posterize',
SEPIA: 'sepia',
SOLARIZE: 'solarize', // Android Only
WHITEBOARD: 'whiteboard' // Android Only
AQUA: 'aqua', // Android Only
BLACKBOARD: 'blackboard', // Android Only
MONO: 'mono',
NEGATIVE: 'negative',
NONE: 'none',
POSTERIZE: 'posterize',
SEPIA: 'sepia',
SOLARIZE: 'solarize', // Android Only
WHITEBOARD: 'whiteboard' // Android Only
};
CameraPreview.CAMERA_DIRECTION = {
BACK: 'back',
FRONT: 'front'
BACK: 'back',
FRONT: 'front'
};
module.exports = CameraPreview;