@capgo/camera-preview 6.1.5 → 6.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -205
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraActivity.java +151 -148
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java +56 -36
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CustomSurfaceView.java +4 -3
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CustomTextureView.java +5 -5
- package/android/src/main/java/com/ahm/capacitor/camera/preview/Preview.java +14 -0
- package/dist/docs.json +104 -173
- package/dist/esm/definitions.d.ts +20 -18
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +4 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/web.d.ts +2 -2
- package/dist/esm/web.js +44 -45
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +45 -46
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +45 -46
- package/dist/plugin.js.map +1 -1
- package/ios/Podfile.lock +2 -2
- package/package.json +28 -33
package/README.md
CHANGED
|
@@ -55,6 +55,9 @@ Open `android/app/src/main/AndroidManifest.xml` and above the closing `</manifes
|
|
|
55
55
|
|
|
56
56
|
```xml
|
|
57
57
|
<uses-permission android:name="android.permission.CAMERA" />
|
|
58
|
+
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
|
59
|
+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
|
60
|
+
|
|
58
61
|
```
|
|
59
62
|
|
|
60
63
|
For more help consult the [Capacitor docs](https://capacitorjs.com/docs/android/configuration#configuring-androidmanifestxml).
|
|
@@ -71,17 +74,6 @@ Add `import '@capgo/camera-preview'` to you entry script in ionic on `app.module
|
|
|
71
74
|
|
|
72
75
|
<docgen-index>
|
|
73
76
|
|
|
74
|
-
* [`start(...)`](#start)
|
|
75
|
-
* [`stop()`](#stop)
|
|
76
|
-
* [`capture(...)`](#capture)
|
|
77
|
-
* [`captureSample(...)`](#capturesample)
|
|
78
|
-
* [`getSupportedFlashModes()`](#getsupportedflashmodes)
|
|
79
|
-
* [`getHorizontalFov()`](#gethorizontalfov)
|
|
80
|
-
* [`setFlashMode(...)`](#setflashmode)
|
|
81
|
-
* [`flip()`](#flip)
|
|
82
|
-
* [`setOpacity(...)`](#setopacity)
|
|
83
|
-
* [`stopRecordVideo()`](#stoprecordvideo)
|
|
84
|
-
* [`startRecordVideo(...)`](#startrecordvideo)
|
|
85
77
|
* [Interfaces](#interfaces)
|
|
86
78
|
* [Type Aliases](#type-aliases)
|
|
87
79
|
|
|
@@ -90,195 +82,6 @@ Add `import '@capgo/camera-preview'` to you entry script in ionic on `app.module
|
|
|
90
82
|
<docgen-api>
|
|
91
83
|
<!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
|
|
92
84
|
|
|
93
|
-
### start(...)
|
|
94
|
-
|
|
95
|
-
```typescript
|
|
96
|
-
start(options: CameraPreviewOptions) => any
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
Start the camera preview instance.
|
|
100
|
-
|
|
101
|
-
| Param | Type | Description |
|
|
102
|
-
| ------------- | --------------------------------------------------------------------- | -------------------------------------------- |
|
|
103
|
-
| **`options`** | <code><a href="#camerapreviewoptions">CameraPreviewOptions</a></code> | the options to start the camera preview with |
|
|
104
|
-
|
|
105
|
-
**Returns:** <code>any</code>
|
|
106
|
-
|
|
107
|
-
**Since:** 0.0.1
|
|
108
|
-
|
|
109
|
-
--------------------
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
### stop()
|
|
113
|
-
|
|
114
|
-
```typescript
|
|
115
|
-
stop() => any
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
Stop the camera preview instance.
|
|
119
|
-
|
|
120
|
-
**Returns:** <code>any</code>
|
|
121
|
-
|
|
122
|
-
**Since:** 0.0.1
|
|
123
|
-
|
|
124
|
-
--------------------
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
### capture(...)
|
|
128
|
-
|
|
129
|
-
```typescript
|
|
130
|
-
capture(options: CameraPreviewPictureOptions) => any
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
Switch camera.
|
|
134
|
-
|
|
135
|
-
| Param | Type | Description |
|
|
136
|
-
| ------------- | ----------------------------------------------------------------------------------- | ------------------------------------- |
|
|
137
|
-
| **`options`** | <code><a href="#camerapreviewpictureoptions">CameraPreviewPictureOptions</a></code> | the options to switch the camera with |
|
|
138
|
-
|
|
139
|
-
**Returns:** <code>any</code>
|
|
140
|
-
|
|
141
|
-
**Since:** 0.0.1
|
|
142
|
-
|
|
143
|
-
--------------------
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
### captureSample(...)
|
|
147
|
-
|
|
148
|
-
```typescript
|
|
149
|
-
captureSample(options: CameraSampleOptions) => any
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
Capture a sample image.
|
|
153
|
-
|
|
154
|
-
| Param | Type | Description |
|
|
155
|
-
| ------------- | ------------------------------------------------------------------- | -------------------------------------------- |
|
|
156
|
-
| **`options`** | <code><a href="#camerasampleoptions">CameraSampleOptions</a></code> | the options to capture the sample image with |
|
|
157
|
-
|
|
158
|
-
**Returns:** <code>any</code>
|
|
159
|
-
|
|
160
|
-
**Since:** 0.0.1
|
|
161
|
-
|
|
162
|
-
--------------------
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
### getSupportedFlashModes()
|
|
166
|
-
|
|
167
|
-
```typescript
|
|
168
|
-
getSupportedFlashModes() => any
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
Get supported flash modes.
|
|
172
|
-
|
|
173
|
-
**Returns:** <code>any</code>
|
|
174
|
-
|
|
175
|
-
**Since:** 0.0.1
|
|
176
|
-
|
|
177
|
-
--------------------
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
### getHorizontalFov()
|
|
181
|
-
|
|
182
|
-
```typescript
|
|
183
|
-
getHorizontalFov() => any
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
Get horizontal field of view.
|
|
187
|
-
|
|
188
|
-
**Returns:** <code>any</code>
|
|
189
|
-
|
|
190
|
-
**Since:** 0.0.1
|
|
191
|
-
|
|
192
|
-
--------------------
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
### setFlashMode(...)
|
|
196
|
-
|
|
197
|
-
```typescript
|
|
198
|
-
setFlashMode(options: { flashMode: CameraPreviewFlashMode | string; }) => any
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
Set flash mode.
|
|
202
|
-
|
|
203
|
-
| Param | Type | Description |
|
|
204
|
-
| ------------- | ----------------------------------- | -------------------------------------- |
|
|
205
|
-
| **`options`** | <code>{ flashMode: string; }</code> | the options to set the flash mode with |
|
|
206
|
-
|
|
207
|
-
**Returns:** <code>any</code>
|
|
208
|
-
|
|
209
|
-
**Since:** 0.0.1
|
|
210
|
-
|
|
211
|
-
--------------------
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
### flip()
|
|
215
|
-
|
|
216
|
-
```typescript
|
|
217
|
-
flip() => any
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
Flip camera.
|
|
221
|
-
|
|
222
|
-
**Returns:** <code>any</code>
|
|
223
|
-
|
|
224
|
-
**Since:** 0.0.1
|
|
225
|
-
|
|
226
|
-
--------------------
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
### setOpacity(...)
|
|
230
|
-
|
|
231
|
-
```typescript
|
|
232
|
-
setOpacity(options: CameraOpacityOptions) => any
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
Set opacity.
|
|
236
|
-
|
|
237
|
-
| Param | Type | Description |
|
|
238
|
-
| ------------- | --------------------------------------------------------------------- | ------------------------------------------ |
|
|
239
|
-
| **`options`** | <code><a href="#cameraopacityoptions">CameraOpacityOptions</a></code> | the options to set the camera opacity with |
|
|
240
|
-
|
|
241
|
-
**Returns:** <code>any</code>
|
|
242
|
-
|
|
243
|
-
**Since:** 0.0.1
|
|
244
|
-
|
|
245
|
-
--------------------
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
### stopRecordVideo()
|
|
249
|
-
|
|
250
|
-
```typescript
|
|
251
|
-
stopRecordVideo() => any
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
Stop recording video.
|
|
255
|
-
|
|
256
|
-
**Returns:** <code>any</code>
|
|
257
|
-
|
|
258
|
-
**Since:** 0.0.1
|
|
259
|
-
|
|
260
|
-
--------------------
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
### startRecordVideo(...)
|
|
264
|
-
|
|
265
|
-
```typescript
|
|
266
|
-
startRecordVideo(options: CameraPreviewOptions) => any
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
Start recording video.
|
|
270
|
-
|
|
271
|
-
| Param | Type | Description |
|
|
272
|
-
| ------------- | --------------------------------------------------------------------- | ----------------------------------------- |
|
|
273
|
-
| **`options`** | <code><a href="#camerapreviewoptions">CameraPreviewOptions</a></code> | the options to start recording video with |
|
|
274
|
-
|
|
275
|
-
**Returns:** <code>any</code>
|
|
276
|
-
|
|
277
|
-
**Since:** 0.0.1
|
|
278
|
-
|
|
279
|
-
--------------------
|
|
280
|
-
|
|
281
|
-
|
|
282
85
|
### Interfaces
|
|
283
86
|
|
|
284
87
|
|
|
@@ -298,7 +101,7 @@ Start recording video.
|
|
|
298
101
|
| **`position`** | <code>string</code> | Choose the camera to use 'front' or 'rear', default 'front' |
|
|
299
102
|
| **`storeToFile`** | <code>boolean</code> | Defaults to false - Capture images to a file and return the file path instead of returning base64 encoded data |
|
|
300
103
|
| **`disableExifHeaderStripping`** | <code>boolean</code> | Defaults to false - Android Only - Disable automatic rotation of the image, and let the browser deal with it (keep reading on how to achieve it) |
|
|
301
|
-
| **`enableHighResolution`** | <code>boolean</code> | Defaults to false - iOS only - Activate high resolution image capture so that output images are from the highest resolution possible on the device
|
|
104
|
+
| **`enableHighResolution`** | <code>boolean</code> | Defaults to false - iOS only - Activate high resolution image capture so that output images are from the highest resolution possible on the device |
|
|
302
105
|
| **`disableAudio`** | <code>boolean</code> | Defaults to false - Web only - Disables audio stream to prevent permission requests and output switching |
|
|
303
106
|
| **`lockAndroidOrientation`** | <code>boolean</code> | Android Only - Locks device orientation when camera is showing. |
|
|
304
107
|
| **`enableOpacity`** | <code>boolean</code> | Defaults to false - Android and Web only. Set if camera preview can change opacity. |
|
|
@@ -334,16 +137,16 @@ Start recording video.
|
|
|
334
137
|
|
|
335
138
|
#### CameraPosition
|
|
336
139
|
|
|
337
|
-
<code>
|
|
140
|
+
<code>'rear' | 'front'</code>
|
|
338
141
|
|
|
339
142
|
|
|
340
143
|
#### PictureFormat
|
|
341
144
|
|
|
342
|
-
<code>
|
|
145
|
+
<code>'jpeg' | 'png'</code>
|
|
343
146
|
|
|
344
147
|
|
|
345
148
|
#### CameraPreviewFlashMode
|
|
346
149
|
|
|
347
|
-
<code>
|
|
150
|
+
<code>'off' | 'on' | 'auto' | 'red-eye' | 'torch'</code>
|
|
348
151
|
|
|
349
|
-
</docgen-api>
|
|
152
|
+
</docgen-api>
|
|
@@ -8,8 +8,6 @@ import android.content.res.Configuration;
|
|
|
8
8
|
import android.graphics.Bitmap;
|
|
9
9
|
import android.graphics.Bitmap.CompressFormat;
|
|
10
10
|
import android.graphics.BitmapFactory;
|
|
11
|
-
import android.graphics.Canvas;
|
|
12
|
-
import android.graphics.ImageFormat;
|
|
13
11
|
import android.graphics.Matrix;
|
|
14
12
|
import android.graphics.Rect;
|
|
15
13
|
import android.graphics.YuvImage;
|
|
@@ -28,9 +26,6 @@ import android.view.Gravity;
|
|
|
28
26
|
import android.view.LayoutInflater;
|
|
29
27
|
import android.view.MotionEvent;
|
|
30
28
|
import android.view.Surface;
|
|
31
|
-
import android.view.Surface;
|
|
32
|
-
import android.view.SurfaceHolder;
|
|
33
|
-
import android.view.SurfaceView;
|
|
34
29
|
import android.view.View;
|
|
35
30
|
import android.view.ViewGroup;
|
|
36
31
|
import android.view.ViewTreeObserver;
|
|
@@ -43,7 +38,9 @@ import java.io.File;
|
|
|
43
38
|
import java.io.FileOutputStream;
|
|
44
39
|
import java.io.IOException;
|
|
45
40
|
import java.util.Arrays;
|
|
41
|
+
import java.util.Collections;
|
|
46
42
|
import java.util.List;
|
|
43
|
+
import java.util.Objects;
|
|
47
44
|
import java.util.UUID;
|
|
48
45
|
|
|
49
46
|
public class CameraActivity extends Fragment {
|
|
@@ -84,7 +81,7 @@ public class CameraActivity extends Fragment {
|
|
|
84
81
|
STOPPED,
|
|
85
82
|
}
|
|
86
83
|
|
|
87
|
-
private RecordingState mRecordingState = RecordingState.INITIALIZING;
|
|
84
|
+
private final RecordingState mRecordingState = RecordingState.INITIALIZING;
|
|
88
85
|
private MediaRecorder mRecorder = null;
|
|
89
86
|
private String recordFilePath;
|
|
90
87
|
|
|
@@ -460,7 +457,6 @@ public class CameraActivity extends Fragment {
|
|
|
460
457
|
if (mCamera != null) {
|
|
461
458
|
setDefaultCameraId();
|
|
462
459
|
mPreview.setCamera(null, -1);
|
|
463
|
-
mCamera.setPreviewCallback(null);
|
|
464
460
|
mCamera.release();
|
|
465
461
|
mCamera = null;
|
|
466
462
|
}
|
|
@@ -533,7 +529,7 @@ public class CameraActivity extends Fragment {
|
|
|
533
529
|
getNumberOfCameras();
|
|
534
530
|
Log.d(TAG, "cameraCurrentlyLocked new: " + cameraCurrentlyLocked);
|
|
535
531
|
} catch (Exception exception) {
|
|
536
|
-
Log.d(TAG, exception.getMessage());
|
|
532
|
+
Log.d(TAG, Objects.requireNonNull(exception.getMessage()));
|
|
537
533
|
}
|
|
538
534
|
|
|
539
535
|
// Acquire the next camera and request Preview to reconfigure parameters.
|
|
@@ -622,7 +618,7 @@ public class CameraActivity extends Fragment {
|
|
|
622
618
|
cache = getActivity().getCacheDir();
|
|
623
619
|
|
|
624
620
|
// Create the cache directory if it doesn't exist
|
|
625
|
-
cache.mkdirs();
|
|
621
|
+
final boolean mkdirs = cache.mkdirs();
|
|
626
622
|
return cache.getAbsolutePath();
|
|
627
623
|
}
|
|
628
624
|
|
|
@@ -640,39 +636,109 @@ public class CameraActivity extends Fragment {
|
|
|
640
636
|
Log.d(TAG, "CameraPreview jpegPictureCallback");
|
|
641
637
|
|
|
642
638
|
try {
|
|
643
|
-
|
|
644
|
-
Matrix matrix = new Matrix();
|
|
645
|
-
if (cameraCurrentlyLocked == Camera.CameraInfo.CAMERA_FACING_FRONT) {
|
|
646
|
-
matrix.preScale(1.0f, -1.0f);
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
ExifInterface exifInterface = new ExifInterface(
|
|
650
|
-
new ByteArrayInputStream(data)
|
|
651
|
-
);
|
|
652
|
-
int rotation = exifInterface.getAttributeInt(
|
|
653
|
-
ExifInterface.TAG_ORIENTATION,
|
|
654
|
-
ExifInterface.ORIENTATION_NORMAL
|
|
655
|
-
);
|
|
656
|
-
int rotationInDegrees = exifToDegrees(rotation);
|
|
639
|
+
Log.d(TAG, "Inside jpegPictureCallback");
|
|
657
640
|
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
641
|
+
if (!disableExifHeaderStripping) {
|
|
642
|
+
try {
|
|
643
|
+
ExifInterface exifInterface = new ExifInterface(
|
|
644
|
+
new ByteArrayInputStream(data)
|
|
645
|
+
);
|
|
646
|
+
int orientation = exifInterface.getAttributeInt(
|
|
647
|
+
ExifInterface.TAG_ORIENTATION,
|
|
648
|
+
ExifInterface.ORIENTATION_NORMAL
|
|
649
|
+
);
|
|
650
|
+
Log.d(TAG, "EXIF Orientation: " + orientation);
|
|
661
651
|
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
652
|
+
int rotation = 0;
|
|
653
|
+
switch (orientation) {
|
|
654
|
+
case ExifInterface.ORIENTATION_ROTATE_90:
|
|
655
|
+
rotation = 90;
|
|
656
|
+
break;
|
|
657
|
+
case ExifInterface.ORIENTATION_ROTATE_180:
|
|
658
|
+
rotation = 180;
|
|
659
|
+
break;
|
|
660
|
+
case ExifInterface.ORIENTATION_ROTATE_270:
|
|
661
|
+
rotation = 270;
|
|
662
|
+
break;
|
|
663
|
+
}
|
|
664
|
+
Log.d(
|
|
665
|
+
TAG,
|
|
666
|
+
"Camera facing: " +
|
|
667
|
+
(cameraCurrentlyLocked == Camera.CameraInfo.CAMERA_FACING_FRONT
|
|
668
|
+
? "front"
|
|
669
|
+
: "rear")
|
|
670
|
+
);
|
|
671
|
+
Log.d(TAG, "Image rotation: " + rotation);
|
|
672
|
+
Log.d(
|
|
673
|
+
TAG,
|
|
674
|
+
"Image flipped: " +
|
|
675
|
+
(cameraCurrentlyLocked == Camera.CameraInfo.CAMERA_FACING_FRONT)
|
|
676
|
+
);
|
|
666
677
|
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
678
|
+
if (
|
|
679
|
+
cameraCurrentlyLocked == Camera.CameraInfo.CAMERA_FACING_FRONT
|
|
680
|
+
) {
|
|
681
|
+
Log.d(TAG, "Front camera EXIF Orientation: " + orientation);
|
|
682
|
+
// Rotate the bitmap based on the orientation value
|
|
683
|
+
Matrix matrix = new Matrix();
|
|
684
|
+
switch (orientation) {
|
|
685
|
+
case ExifInterface.ORIENTATION_ROTATE_90:
|
|
686
|
+
matrix.postRotate(270);
|
|
687
|
+
break;
|
|
688
|
+
case ExifInterface.ORIENTATION_ROTATE_180:
|
|
689
|
+
matrix.postRotate(180);
|
|
690
|
+
break;
|
|
691
|
+
case ExifInterface.ORIENTATION_ROTATE_270:
|
|
692
|
+
matrix.postRotate(90);
|
|
693
|
+
break;
|
|
694
|
+
}
|
|
695
|
+
// Flip the bitmap horizontally for the front camera
|
|
696
|
+
matrix.postScale(-1, 1);
|
|
697
|
+
Bitmap bitmap = BitmapFactory.decodeByteArray(
|
|
698
|
+
data,
|
|
699
|
+
0,
|
|
700
|
+
data.length
|
|
701
|
+
);
|
|
702
|
+
bitmap = Bitmap.createBitmap(
|
|
703
|
+
bitmap,
|
|
704
|
+
0,
|
|
705
|
+
0,
|
|
706
|
+
bitmap.getWidth(),
|
|
707
|
+
bitmap.getHeight(),
|
|
708
|
+
matrix,
|
|
709
|
+
true
|
|
710
|
+
);
|
|
711
|
+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
712
|
+
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
|
|
713
|
+
data = outputStream.toByteArray();
|
|
714
|
+
} else if (rotation != 0) {
|
|
715
|
+
Matrix matrix = new Matrix();
|
|
716
|
+
matrix.postRotate(rotation);
|
|
717
|
+
Bitmap bitmap = BitmapFactory.decodeByteArray(
|
|
718
|
+
data,
|
|
719
|
+
0,
|
|
720
|
+
data.length
|
|
721
|
+
);
|
|
722
|
+
bitmap = Bitmap.createBitmap(
|
|
723
|
+
bitmap,
|
|
724
|
+
0,
|
|
725
|
+
0,
|
|
726
|
+
bitmap.getWidth(),
|
|
727
|
+
bitmap.getHeight(),
|
|
728
|
+
matrix,
|
|
729
|
+
true
|
|
730
|
+
);
|
|
731
|
+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
732
|
+
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
|
|
733
|
+
data = outputStream.toByteArray();
|
|
734
|
+
}
|
|
735
|
+
} catch (IOException e) {
|
|
736
|
+
Log.e(TAG, "Failed to read EXIF data", e);
|
|
670
737
|
}
|
|
671
738
|
}
|
|
672
739
|
|
|
673
740
|
if (!storeToFile) {
|
|
674
741
|
String encodedImage = Base64.encodeToString(data, Base64.NO_WRAP);
|
|
675
|
-
|
|
676
742
|
eventListener.onPictureTaken(encodedImage);
|
|
677
743
|
} else {
|
|
678
744
|
String path = getTempFilePath();
|
|
@@ -699,105 +765,6 @@ public class CameraActivity extends Fragment {
|
|
|
699
765
|
}
|
|
700
766
|
};
|
|
701
767
|
|
|
702
|
-
private Camera.Size getOptimalPictureSize(
|
|
703
|
-
final int width,
|
|
704
|
-
final int height,
|
|
705
|
-
final Camera.Size previewSize,
|
|
706
|
-
final List<Camera.Size> supportedSizes
|
|
707
|
-
) {
|
|
708
|
-
/*
|
|
709
|
-
get the supportedPictureSize that:
|
|
710
|
-
- matches exactly width and height
|
|
711
|
-
- has the closest aspect ratio to the preview aspect ratio
|
|
712
|
-
- has picture.width and picture.height closest to width and height
|
|
713
|
-
- has the highest supported picture width and height up to 2 Megapixel if width == 0 || height == 0
|
|
714
|
-
*/
|
|
715
|
-
Camera.Size size = mCamera.new Size(width, height);
|
|
716
|
-
|
|
717
|
-
// convert to landscape if necessary
|
|
718
|
-
if (size.width < size.height) {
|
|
719
|
-
int temp = size.width;
|
|
720
|
-
size.width = size.height;
|
|
721
|
-
size.height = temp;
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
Camera.Size requestedSize = mCamera.new Size(size.width, size.height);
|
|
725
|
-
|
|
726
|
-
double previewAspectRatio =
|
|
727
|
-
(double) previewSize.width / (double) previewSize.height;
|
|
728
|
-
|
|
729
|
-
if (previewAspectRatio < 1.0) {
|
|
730
|
-
// reset ratio to landscape
|
|
731
|
-
previewAspectRatio = 1.0 / previewAspectRatio;
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
Log.d(TAG, "CameraPreview previewAspectRatio " + previewAspectRatio);
|
|
735
|
-
|
|
736
|
-
double aspectTolerance = 0.1;
|
|
737
|
-
double bestDifference = Double.MAX_VALUE;
|
|
738
|
-
|
|
739
|
-
for (int i = 0; i < supportedSizes.size(); i++) {
|
|
740
|
-
Camera.Size supportedSize = supportedSizes.get(i);
|
|
741
|
-
|
|
742
|
-
// Perfect match
|
|
743
|
-
if (supportedSize.equals(requestedSize)) {
|
|
744
|
-
Log.d(
|
|
745
|
-
TAG,
|
|
746
|
-
"CameraPreview optimalPictureSize " +
|
|
747
|
-
supportedSize.width +
|
|
748
|
-
'x' +
|
|
749
|
-
supportedSize.height
|
|
750
|
-
);
|
|
751
|
-
return supportedSize;
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
double difference = Math.abs(
|
|
755
|
-
previewAspectRatio -
|
|
756
|
-
((double) supportedSize.width / (double) supportedSize.height)
|
|
757
|
-
);
|
|
758
|
-
|
|
759
|
-
if (difference < bestDifference - aspectTolerance) {
|
|
760
|
-
// better aspectRatio found
|
|
761
|
-
if (
|
|
762
|
-
(width != 0 && height != 0) ||
|
|
763
|
-
(supportedSize.width * supportedSize.height < 2048 * 1024)
|
|
764
|
-
) {
|
|
765
|
-
size.width = supportedSize.width;
|
|
766
|
-
size.height = supportedSize.height;
|
|
767
|
-
bestDifference = difference;
|
|
768
|
-
}
|
|
769
|
-
} else if (difference < bestDifference + aspectTolerance) {
|
|
770
|
-
// same aspectRatio found (within tolerance)
|
|
771
|
-
if (width == 0 || height == 0) {
|
|
772
|
-
// set highest supported resolution below 2 Megapixel
|
|
773
|
-
if (
|
|
774
|
-
(size.width < supportedSize.width) &&
|
|
775
|
-
(supportedSize.width * supportedSize.height < 2048 * 1024)
|
|
776
|
-
) {
|
|
777
|
-
size.width = supportedSize.width;
|
|
778
|
-
size.height = supportedSize.height;
|
|
779
|
-
}
|
|
780
|
-
} else {
|
|
781
|
-
// check if this pictureSize closer to requested width and height
|
|
782
|
-
if (
|
|
783
|
-
Math.abs(
|
|
784
|
-
width * height - supportedSize.width * supportedSize.height
|
|
785
|
-
) <
|
|
786
|
-
Math.abs(width * height - size.width * size.height)
|
|
787
|
-
) {
|
|
788
|
-
size.width = supportedSize.width;
|
|
789
|
-
size.height = supportedSize.height;
|
|
790
|
-
}
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
Log.d(
|
|
795
|
-
TAG,
|
|
796
|
-
"CameraPreview optimalPictureSize " + size.width + 'x' + size.height
|
|
797
|
-
);
|
|
798
|
-
return size;
|
|
799
|
-
}
|
|
800
|
-
|
|
801
768
|
static byte[] rotateNV21(
|
|
802
769
|
final byte[] yuv,
|
|
803
770
|
final int width,
|
|
@@ -899,6 +866,43 @@ public class CameraActivity extends Fragment {
|
|
|
899
866
|
);
|
|
900
867
|
}
|
|
901
868
|
|
|
869
|
+
private Camera.Size getOptimalPictureSizeForPreview(
|
|
870
|
+
int width,
|
|
871
|
+
int height,
|
|
872
|
+
Camera.Size previewSize,
|
|
873
|
+
List<Camera.Size> supportedSizes
|
|
874
|
+
) {
|
|
875
|
+
Log.d(TAG, "Requested picture size: " + width + "x" + height);
|
|
876
|
+
Log.d(TAG, "Preview size: " + previewSize.width + "x" + previewSize.height);
|
|
877
|
+
double targetRatio = (double) previewSize.width / previewSize.height;
|
|
878
|
+
Camera.Size optimalSize = null;
|
|
879
|
+
double minDiff = Double.MAX_VALUE;
|
|
880
|
+
|
|
881
|
+
for (Camera.Size size : supportedSizes) {
|
|
882
|
+
double ratio = (double) size.width / size.height;
|
|
883
|
+
if (Math.abs(ratio - targetRatio) > 0.1) continue;
|
|
884
|
+
if (Math.abs(size.height - height) < minDiff) {
|
|
885
|
+
optimalSize = size;
|
|
886
|
+
minDiff = Math.abs(size.height - height);
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
if (optimalSize == null) {
|
|
891
|
+
minDiff = Double.MAX_VALUE;
|
|
892
|
+
for (Camera.Size size : supportedSizes) {
|
|
893
|
+
if (Math.abs(size.height - height) < minDiff) {
|
|
894
|
+
optimalSize = size;
|
|
895
|
+
minDiff = Math.abs(size.height - height);
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
Log.d(
|
|
900
|
+
TAG,
|
|
901
|
+
"Optimal picture size: " + optimalSize.width + "x" + optimalSize.height
|
|
902
|
+
);
|
|
903
|
+
return optimalSize;
|
|
904
|
+
}
|
|
905
|
+
|
|
902
906
|
public void takePicture(
|
|
903
907
|
final int width,
|
|
904
908
|
final int height,
|
|
@@ -925,7 +929,7 @@ public class CameraActivity extends Fragment {
|
|
|
925
929
|
public void run() {
|
|
926
930
|
Camera.Parameters params = mCamera.getParameters();
|
|
927
931
|
|
|
928
|
-
Camera.Size size =
|
|
932
|
+
Camera.Size size = getOptimalPictureSizeForPreview(
|
|
929
933
|
width,
|
|
930
934
|
height,
|
|
931
935
|
params.getPreviewSize(),
|
|
@@ -1027,11 +1031,7 @@ public class CameraActivity extends Fragment {
|
|
|
1027
1031
|
|
|
1028
1032
|
Camera.Parameters cameraParams = mCamera.getParameters();
|
|
1029
1033
|
if (withFlash) {
|
|
1030
|
-
cameraParams.setFlashMode(
|
|
1031
|
-
withFlash
|
|
1032
|
-
? Camera.Parameters.FLASH_MODE_TORCH
|
|
1033
|
-
: Camera.Parameters.FLASH_MODE_OFF
|
|
1034
|
-
);
|
|
1034
|
+
cameraParams.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
|
|
1035
1035
|
mCamera.setParameters(cameraParams);
|
|
1036
1036
|
mCamera.startPreview();
|
|
1037
1037
|
}
|
|
@@ -1127,9 +1127,6 @@ public class CameraActivity extends Fragment {
|
|
|
1127
1127
|
|
|
1128
1128
|
int degrees = 0;
|
|
1129
1129
|
switch (currentScreenRotation) {
|
|
1130
|
-
case Surface.ROTATION_0:
|
|
1131
|
-
degrees = 0;
|
|
1132
|
-
break;
|
|
1133
1130
|
case Surface.ROTATION_90:
|
|
1134
1131
|
degrees = 90;
|
|
1135
1132
|
break;
|
|
@@ -1139,6 +1136,8 @@ public class CameraActivity extends Fragment {
|
|
|
1139
1136
|
case Surface.ROTATION_270:
|
|
1140
1137
|
degrees = 270;
|
|
1141
1138
|
break;
|
|
1139
|
+
default:
|
|
1140
|
+
break;
|
|
1142
1141
|
}
|
|
1143
1142
|
|
|
1144
1143
|
int orientation;
|
|
@@ -1179,9 +1178,11 @@ public class CameraActivity extends Fragment {
|
|
|
1179
1178
|
((AudioManager) activity
|
|
1180
1179
|
.getApplicationContext()
|
|
1181
1180
|
.getSystemService(Context.AUDIO_SERVICE));
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1181
|
+
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
|
|
1182
|
+
int direction = mute
|
|
1183
|
+
? AudioManager.ADJUST_MUTE
|
|
1184
|
+
: AudioManager.ADJUST_UNMUTE;
|
|
1185
|
+
}
|
|
1185
1186
|
}
|
|
1186
1187
|
|
|
1187
1188
|
public void setFocusArea(
|
|
@@ -1196,12 +1197,14 @@ public class CameraActivity extends Fragment {
|
|
|
1196
1197
|
|
|
1197
1198
|
Rect focusRect = calculateTapArea(pointX, pointY, 1f);
|
|
1198
1199
|
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
|
|
1199
|
-
parameters.setFocusAreas(
|
|
1200
|
+
parameters.setFocusAreas(
|
|
1201
|
+
Collections.singletonList(new Camera.Area(focusRect, 1000))
|
|
1202
|
+
);
|
|
1200
1203
|
|
|
1201
1204
|
if (parameters.getMaxNumMeteringAreas() > 0) {
|
|
1202
1205
|
Rect meteringRect = calculateTapArea(pointX, pointY, 1.5f);
|
|
1203
1206
|
parameters.setMeteringAreas(
|
|
1204
|
-
|
|
1207
|
+
Collections.singletonList(new Camera.Area(meteringRect, 1000))
|
|
1205
1208
|
);
|
|
1206
1209
|
}
|
|
1207
1210
|
|
|
@@ -1209,7 +1212,7 @@ public class CameraActivity extends Fragment {
|
|
|
1209
1212
|
setCameraParameters(parameters);
|
|
1210
1213
|
mCamera.autoFocus(callback);
|
|
1211
1214
|
} catch (Exception e) {
|
|
1212
|
-
Log.d(TAG, e.getMessage());
|
|
1215
|
+
Log.d(TAG, Objects.requireNonNull(e.getMessage()));
|
|
1213
1216
|
callback.onAutoFocus(false, this.mCamera);
|
|
1214
1217
|
}
|
|
1215
1218
|
}
|