3
3
import android .app .Activity ;
4
4
import android .util .Log ;
5
5
import android .util .Size ;
6
+ import android .util .SparseIntArray ;
6
7
import android .os .Handler ;
7
8
import android .os .HandlerThread ;
8
9
import android .content .Context ;
@@ -45,6 +46,30 @@ public class CanvasCamera extends CordovaPlugin
45
46
{
46
47
private final static String TAG = "SimpleCamera" ;
47
48
49
+ /**
50
+ * Conversion from screen rotation to JPEG orientation for back facing camera.
51
+ */
52
+ private static final SparseIntArray BACK_CAMERA_ORIENTATIONS = new SparseIntArray ();
53
+
54
+ static {
55
+ BACK_CAMERA_ORIENTATIONS .append (Surface .ROTATION_0 , 90 );
56
+ BACK_CAMERA_ORIENTATIONS .append (Surface .ROTATION_90 , 0 );
57
+ BACK_CAMERA_ORIENTATIONS .append (Surface .ROTATION_180 , 270 );
58
+ BACK_CAMERA_ORIENTATIONS .append (Surface .ROTATION_270 , 180 );
59
+ }
60
+
61
+ /**
62
+ * Conversion from screen rotation to JPEG orientation for front facing camera.
63
+ */
64
+ private static final SparseIntArray FRONT_CAMERA_ORIENTATIONS = new SparseIntArray ();
65
+
66
+ static {
67
+ FRONT_CAMERA_ORIENTATIONS .append (Surface .ROTATION_0 , 270 );
68
+ FRONT_CAMERA_ORIENTATIONS .append (Surface .ROTATION_90 , 0 );
69
+ FRONT_CAMERA_ORIENTATIONS .append (Surface .ROTATION_180 , 90 );
70
+ FRONT_CAMERA_ORIENTATIONS .append (Surface .ROTATION_270 , 180 );
71
+ }
72
+
48
73
private Activity mActivity ;
49
74
private CallbackContext mCallbackContext ;
50
75
@@ -53,6 +78,7 @@ public class CanvasCamera extends CordovaPlugin
53
78
private CameraDevice mCamera ;
54
79
private String mCameraId ;
55
80
private ImageReader mReader = null ;
81
+ private int mFileId = 0 ;
56
82
private HandlerThread mBackgroundThread ;
57
83
private Handler mBackgroundHandler ;
58
84
private SimpleImageListener mListener = null ;
@@ -74,6 +100,10 @@ else if ("setFlashMode".equals(action)) {
74
100
setFlashMode (args , callbackContext );
75
101
return true ;
76
102
}
103
+ else if ("setCameraPosition" .equals (action )) {
104
+ setCameraPosition (args , callbackContext );
105
+ return true ;
106
+ }
77
107
78
108
return false ;
79
109
}
@@ -86,7 +116,7 @@ private void startCapture(JSONArray args, CallbackContext callbackContext)
86
116
Log .d (TAG , "camera manager obtained" );
87
117
88
118
try {
89
- mCameraId = mCameraManager . getCameraIdList ()[ 0 ] ;
119
+ mCameraId = getCameraIdForOrientation ( CameraCharacteristics . LENS_FACING_BACK ) ;
90
120
startBackgroundThread ();
91
121
mCameraManager .openCamera (mCameraId , cameraStateCallback , null );
92
122
@@ -137,7 +167,42 @@ private void setFlashMode(JSONArray args, CallbackContext callbackContext)
137
167
callbackContext .success ();
138
168
}
139
169
catch (Exception e ){
140
- callbackContext .error ("Failed to stop capture" );
170
+ callbackContext .error ("Failed to set flash mode" );
171
+ }
172
+ }
173
+
174
+ private void setCameraPosition (JSONArray args , CallbackContext callbackContext )
175
+ {
176
+ try {
177
+ String cameraPosition = args .getString (0 );
178
+
179
+ Log .d (TAG , "camera is gonna be switched to " + cameraPosition );
180
+
181
+ int lensOrientation = CameraCharacteristics .LENS_FACING_BACK ;
182
+
183
+ if (cameraPosition .equals ("front" )) {
184
+ lensOrientation = CameraCharacteristics .LENS_FACING_FRONT ;
185
+ }
186
+
187
+ mCameraId = getCameraIdForOrientation (lensOrientation );
188
+
189
+ if (mCameraId != null ) {
190
+ stopBackgroundThread ();
191
+ mCameraSession .close ();
192
+ mCamera .close ();
193
+
194
+ startBackgroundThread ();
195
+ mCameraManager .openCamera (mCameraId , cameraStateCallback , null );
196
+
197
+ Log .d (TAG , "camera switched" );
198
+ callbackContext .success ();
199
+ }
200
+ else {
201
+ callbackContext .error ("Failed to switch camera" );
202
+ }
203
+ }
204
+ catch (Exception e ){
205
+ callbackContext .error ("Failed to switch camera" );
141
206
}
142
207
}
143
208
@@ -157,12 +222,12 @@ public void onOpened(CameraDevice camera) {
157
222
CameraCharacteristics .SCALER_STREAM_CONFIGURATION_MAP );
158
223
159
224
Size [] outputSizes = map .getOutputSizes (ImageFormat .JPEG );
160
- Size previewSize = outputSizes [ outputSizes . length - 1 ] ;
225
+ Size previewSize = chooseOptimalSize ( outputSizes , 352 , 288 ) ;
161
226
162
227
Log .d (TAG , "Creating ImageReader with size " + previewSize .toString () + " for camera " + mCameraId );
163
228
164
229
mReader = ImageReader .newInstance (previewSize .getWidth (), previewSize .getHeight (),
165
- ImageFormat .JPEG , /*maxImages*/ 10 );
230
+ ImageFormat .JPEG , /*maxImages*/ 2 );
166
231
167
232
mListener = new SimpleImageListener ();
168
233
@@ -221,6 +286,23 @@ private CaptureRequest prepareCaptureRequest(int flashMode) {
221
286
mCamera .createCaptureRequest (CameraDevice .TEMPLATE_PREVIEW );
222
287
223
288
captureBuilder .addTarget (surface );
289
+ captureBuilder .set (CaptureRequest .COLOR_CORRECTION_MODE ,
290
+ CaptureRequest .COLOR_CORRECTION_MODE_FAST );
291
+
292
+ int rotation = mActivity .getWindowManager ().getDefaultDisplay ().getRotation ();
293
+
294
+ CameraCharacteristics characteristics = mCameraManager .getCameraCharacteristics (mCameraId );
295
+ int orientation = characteristics .get (CameraCharacteristics .LENS_FACING );
296
+ if (orientation == CameraCharacteristics .LENS_FACING_FRONT ) {
297
+ rotation = FRONT_CAMERA_ORIENTATIONS .get (rotation );
298
+ }
299
+ else {
300
+ rotation = BACK_CAMERA_ORIENTATIONS .get (rotation );
301
+ }
302
+
303
+ Log .d (TAG , "Rotation: " + rotation );
304
+ captureBuilder .set (CaptureRequest .JPEG_ORIENTATION , rotation );
305
+
224
306
captureBuilder .set (CaptureRequest .FLASH_MODE , flashMode );
225
307
226
308
return captureBuilder .build ();
@@ -231,6 +313,29 @@ private CaptureRequest prepareCaptureRequest(int flashMode) {
231
313
}
232
314
}
233
315
316
+ private String getCameraIdForOrientation (int cameraFacingOrientation ) {
317
+ try {
318
+ String [] cameraIdList = mCameraManager .getCameraIdList ();
319
+
320
+ for (final String cameraId : cameraIdList ) {
321
+ CameraCharacteristics characteristics = mCameraManager .getCameraCharacteristics (cameraId );
322
+ int orientation = characteristics .get (CameraCharacteristics .LENS_FACING );
323
+ if (orientation == cameraFacingOrientation ) {
324
+ return cameraId ;
325
+ }
326
+ }
327
+
328
+ if (cameraIdList .length > 0 ) {
329
+ return cameraIdList [0 ];
330
+ }
331
+ } catch (CameraAccessException e ) {
332
+ e .printStackTrace ();
333
+ return null ;
334
+ }
335
+
336
+ return null ;
337
+ }
338
+
234
339
private void startBackgroundThread () {
235
340
mBackgroundThread = new HandlerThread ("CameraBackground" );
236
341
mBackgroundThread .start ();
@@ -252,8 +357,6 @@ private void stopBackgroundThread() {
252
357
}
253
358
254
359
private class SimpleImageListener implements ImageReader .OnImageAvailableListener {
255
- private int mFileId = 0 ;
256
-
257
360
@ Override
258
361
public void onImageAvailable (ImageReader reader ) {
259
362
Image img = reader .acquireLatestImage ();
@@ -305,4 +408,18 @@ public void saveImage(Image image, File file) {
305
408
}
306
409
}
307
410
411
+ private static Size chooseOptimalSize (Size [] choices , int width , int height ) {
412
+ Size bigEnough = choices [0 ];
413
+ for (Size option : choices ) {
414
+ if (option .getWidth () >= width && option .getHeight () >= height
415
+ && option .getWidth () < bigEnough .getWidth ()
416
+ && option .getHeight () < bigEnough .getHeight ()
417
+ ) {
418
+ bigEnough = option ;
419
+ }
420
+ }
421
+
422
+ return bigEnough ;
423
+ }
424
+
308
425
}
0 commit comments