@capgo/camera-preview 3.6.22 → 4.0.0

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.
Files changed (43) hide show
  1. package/README.md +67 -405
  2. package/android/build.gradle +8 -7
  3. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  4. package/android/gradle/wrapper/gradle-wrapper.properties +3 -2
  5. package/android/gradle.properties +1 -1
  6. package/android/gradlew +14 -4
  7. package/android/gradlew.bat +34 -32
  8. package/android/src/androidTest/java/com/getcapacitor/android/ExampleInstrumentedTest.java +6 -6
  9. package/android/src/main/AndroidManifest.xml +1 -1
  10. package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraActivity.java +1105 -854
  11. package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java +543 -428
  12. package/android/src/main/java/com/ahm/capacitor/camera/preview/CustomSurfaceView.java +15 -10
  13. package/android/src/main/java/com/ahm/capacitor/camera/preview/CustomTextureView.java +31 -21
  14. package/android/src/main/java/com/ahm/capacitor/camera/preview/Preview.java +386 -332
  15. package/android/src/main/java/com/ahm/capacitor/camera/preview/TapGestureDetector.java +13 -13
  16. package/android/src/test/java/com/getcapacitor/ExampleUnitTest.java +4 -4
  17. package/dist/docs.json +208 -37
  18. package/dist/esm/definitions.d.ts +76 -3
  19. package/dist/esm/index.d.ts +2 -2
  20. package/dist/esm/index.js +4 -4
  21. package/dist/esm/web.d.ts +2 -2
  22. package/dist/esm/web.js +39 -36
  23. package/dist/esm/web.js.map +1 -1
  24. package/dist/plugin.cjs.js +39 -36
  25. package/dist/plugin.cjs.js.map +1 -1
  26. package/dist/plugin.js +39 -36
  27. package/dist/plugin.js.map +1 -1
  28. package/ios/Plugin/CameraController.swift +1 -1
  29. package/ios/Plugin/Plugin.swift +1 -1
  30. package/ios/Podfile.lock +3 -3
  31. package/package.json +22 -22
  32. package/android/.gradle/7.4.2/checksums/checksums.lock +0 -0
  33. package/android/.gradle/7.4.2/checksums/md5-checksums.bin +0 -0
  34. package/android/.gradle/7.4.2/checksums/sha1-checksums.bin +0 -0
  35. package/android/.gradle/7.4.2/dependencies-accessors/dependencies-accessors.lock +0 -0
  36. package/android/.gradle/7.4.2/dependencies-accessors/gc.properties +0 -0
  37. package/android/.gradle/7.4.2/executionHistory/executionHistory.lock +0 -0
  38. package/android/.gradle/7.4.2/fileChanges/last-build.bin +0 -0
  39. package/android/.gradle/7.4.2/fileHashes/fileHashes.lock +0 -0
  40. package/android/.gradle/7.4.2/gc.properties +0 -0
  41. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  42. package/android/.gradle/buildOutputCleanup/cache.properties +0 -2
  43. package/android/.gradle/vcs-1/gc.properties +0 -0
@@ -14,373 +14,427 @@ import android.widget.RelativeLayout;
14
14
  import java.io.IOException;
15
15
  import java.util.List;
16
16
 
17
- class Preview extends RelativeLayout implements SurfaceHolder.Callback, TextureView.SurfaceTextureListener {
18
-
19
- private final String TAG = "Preview";
20
-
21
- CustomSurfaceView mSurfaceView;
22
- CustomTextureView mTextureView;
23
- SurfaceHolder mHolder;
24
- SurfaceTexture mSurface;
25
- Camera.Size mPreviewSize;
26
- List<Camera.Size> mSupportedPreviewSizes;
27
- Camera mCamera;
28
- int cameraId;
29
- int displayOrientation;
30
- int facing = Camera.CameraInfo.CAMERA_FACING_BACK;
31
- int viewWidth;
32
- int viewHeight;
33
- private boolean enableOpacity = false;
34
- private float opacity = 1F;
35
-
36
- Preview(Context context) {
37
- this(context, false);
17
+ class Preview
18
+ extends RelativeLayout
19
+ implements SurfaceHolder.Callback, TextureView.SurfaceTextureListener {
20
+
21
+ private final String TAG = "Preview";
22
+
23
+ CustomSurfaceView mSurfaceView;
24
+ CustomTextureView mTextureView;
25
+ SurfaceHolder mHolder;
26
+ SurfaceTexture mSurface;
27
+ Camera.Size mPreviewSize;
28
+ List<Camera.Size> mSupportedPreviewSizes;
29
+ Camera mCamera;
30
+ int cameraId;
31
+ int displayOrientation;
32
+ int facing = Camera.CameraInfo.CAMERA_FACING_BACK;
33
+ int viewWidth;
34
+ int viewHeight;
35
+ private boolean enableOpacity = false;
36
+ private float opacity = 1F;
37
+
38
+ Preview(Context context) {
39
+ this(context, false);
40
+ }
41
+
42
+ Preview(Context context, boolean enableOpacity) {
43
+ super(context);
44
+ this.enableOpacity = enableOpacity;
45
+ if (!enableOpacity) {
46
+ mSurfaceView = new CustomSurfaceView(context);
47
+ addView(mSurfaceView);
48
+ requestLayout();
49
+
50
+ // Install a SurfaceHolder.Callback so we get notified when the
51
+ // underlying surface is created and destroyed.
52
+ mHolder = mSurfaceView.getHolder();
53
+ mHolder.addCallback(this);
54
+ mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
55
+ } else {
56
+ // Use a TextureView so we can manage opacity
57
+ mTextureView = new CustomTextureView(context);
58
+ // Install a SurfaceTextureListener so we get notified
59
+ mTextureView.setSurfaceTextureListener(this);
60
+ mTextureView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
61
+ addView(mTextureView);
62
+ requestLayout();
38
63
  }
39
-
40
- Preview(Context context, boolean enableOpacity) {
41
- super(context);
42
- this.enableOpacity = enableOpacity;
43
- if (!enableOpacity) {
44
- mSurfaceView = new CustomSurfaceView(context);
45
- addView(mSurfaceView);
46
- requestLayout();
47
-
48
- // Install a SurfaceHolder.Callback so we get notified when the
49
- // underlying surface is created and destroyed.
50
- mHolder = mSurfaceView.getHolder();
51
- mHolder.addCallback(this);
52
- mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
53
- } else {
54
- // Use a TextureView so we can manage opacity
55
- mTextureView = new CustomTextureView(context);
56
- // Install a SurfaceTextureListener so we get notified
57
- mTextureView.setSurfaceTextureListener(this);
58
- mTextureView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
59
- addView(mTextureView);
60
- requestLayout();
61
- }
64
+ }
65
+
66
+ public void setCamera(Camera camera, int cameraId) {
67
+ if (camera != null) {
68
+ mCamera = camera;
69
+ this.cameraId = cameraId;
70
+ mSupportedPreviewSizes =
71
+ mCamera.getParameters().getSupportedPreviewSizes();
72
+ setCameraDisplayOrientation();
73
+
74
+ List<String> mFocusModes = mCamera
75
+ .getParameters()
76
+ .getSupportedFocusModes();
77
+
78
+ Camera.Parameters params = mCamera.getParameters();
79
+ if (mFocusModes.contains("continuous-picture")) {
80
+ params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
81
+ } else if (mFocusModes.contains("continuous-video")) {
82
+ params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
83
+ } else if (mFocusModes.contains("auto")) {
84
+ params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
85
+ }
86
+ mCamera.setParameters(params);
62
87
  }
63
-
64
- public void setCamera(Camera camera, int cameraId) {
65
- if (camera != null) {
66
- mCamera = camera;
67
- this.cameraId = cameraId;
68
- mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
69
- setCameraDisplayOrientation();
70
-
71
- List<String> mFocusModes = mCamera.getParameters().getSupportedFocusModes();
72
-
73
- Camera.Parameters params = mCamera.getParameters();
74
- if (mFocusModes.contains("continuous-picture")) {
75
- params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
76
- } else if (mFocusModes.contains("continuous-video")) {
77
- params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
78
- } else if (mFocusModes.contains("auto")) {
79
- params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
80
- }
81
- mCamera.setParameters(params);
82
- }
88
+ }
89
+
90
+ public int getDisplayOrientation() {
91
+ return displayOrientation;
92
+ }
93
+
94
+ public int getCameraFacing() {
95
+ return facing;
96
+ }
97
+
98
+ public void printPreviewSize(String from) {
99
+ Log.d(
100
+ TAG,
101
+ "printPreviewSize from " +
102
+ from +
103
+ ": > width: " +
104
+ mPreviewSize.width +
105
+ " height: " +
106
+ mPreviewSize.height
107
+ );
108
+ }
109
+
110
+ public void setCameraPreviewSize() {
111
+ if (mCamera != null) {
112
+ Camera.Parameters parameters = mCamera.getParameters();
113
+ parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
114
+ mCamera.setParameters(parameters);
83
115
  }
84
-
85
- public int getDisplayOrientation() {
86
- return displayOrientation;
116
+ }
117
+
118
+ public void setCameraDisplayOrientation() {
119
+ Camera.CameraInfo info = new Camera.CameraInfo();
120
+ int rotation =
121
+ ((Activity) getContext()).getWindowManager()
122
+ .getDefaultDisplay()
123
+ .getRotation();
124
+ int degrees = 0;
125
+ DisplayMetrics dm = new DisplayMetrics();
126
+
127
+ Camera.getCameraInfo(cameraId, info);
128
+ ((Activity) getContext()).getWindowManager()
129
+ .getDefaultDisplay()
130
+ .getMetrics(dm);
131
+
132
+ switch (rotation) {
133
+ case Surface.ROTATION_0:
134
+ degrees = 0;
135
+ break;
136
+ case Surface.ROTATION_90:
137
+ degrees = 90;
138
+ break;
139
+ case Surface.ROTATION_180:
140
+ degrees = 180;
141
+ break;
142
+ case Surface.ROTATION_270:
143
+ degrees = 270;
144
+ break;
87
145
  }
88
-
89
- public int getCameraFacing() {
90
- return facing;
146
+ facing = info.facing;
147
+ if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
148
+ displayOrientation = (info.orientation + degrees) % 360;
149
+ displayOrientation = (360 - displayOrientation) % 360;
150
+ } else {
151
+ displayOrientation = (info.orientation - degrees + 360) % 360;
91
152
  }
92
153
 
93
- public void printPreviewSize(String from) {
94
- Log.d(TAG, "printPreviewSize from " + from + ": > width: " + mPreviewSize.width + " height: " + mPreviewSize.height);
95
- }
154
+ Log.d(TAG, "screen is rotated " + degrees + "deg from natural");
155
+ Log.d(
156
+ TAG,
157
+ (
158
+ info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT ? "front" : "back"
159
+ ) +
160
+ " camera is oriented -" +
161
+ info.orientation +
162
+ "deg from natural"
163
+ );
164
+ Log.d(TAG, "need to rotate preview " + displayOrientation + "deg");
165
+ mCamera.setDisplayOrientation(displayOrientation);
166
+ }
167
+
168
+ public void switchCamera(Camera camera, int cameraId) {
169
+ try {
170
+ setCamera(camera, cameraId);
171
+
172
+ Log.d("CameraPreview", "before set camera");
173
+
174
+ View v;
175
+ if (enableOpacity) {
176
+ camera.setPreviewTexture(mSurface);
177
+ v = mTextureView;
178
+ } else {
179
+ camera.setPreviewDisplay(mHolder);
180
+ v = mSurfaceView;
181
+ }
182
+
183
+ Log.d("CameraPreview", "before getParameters");
184
+
185
+ Camera.Parameters parameters = camera.getParameters();
186
+
187
+ Log.d("CameraPreview", "before setPreviewSize");
188
+
189
+ mSupportedPreviewSizes = parameters.getSupportedPreviewSizes();
190
+ mPreviewSize =
191
+ getOptimalPreviewSize(
192
+ mSupportedPreviewSizes,
193
+ v.getWidth(),
194
+ v.getHeight()
195
+ );
196
+ parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
197
+ Log.d(TAG, mPreviewSize.width + " " + mPreviewSize.height);
96
198
 
97
- public void setCameraPreviewSize() {
98
- if (mCamera != null) {
99
- Camera.Parameters parameters = mCamera.getParameters();
100
- parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
101
- mCamera.setParameters(parameters);
102
- }
199
+ camera.setParameters(parameters);
200
+ } catch (IOException exception) {
201
+ Log.e(TAG, exception.getMessage());
103
202
  }
104
-
105
- public void setCameraDisplayOrientation() {
106
- Camera.CameraInfo info = new Camera.CameraInfo();
107
- int rotation = ((Activity) getContext()).getWindowManager().getDefaultDisplay().getRotation();
108
- int degrees = 0;
109
- DisplayMetrics dm = new DisplayMetrics();
110
-
111
- Camera.getCameraInfo(cameraId, info);
112
- ((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(dm);
113
-
114
- switch (rotation) {
115
- case Surface.ROTATION_0:
116
- degrees = 0;
117
- break;
118
- case Surface.ROTATION_90:
119
- degrees = 90;
120
- break;
121
- case Surface.ROTATION_180:
122
- degrees = 180;
123
- break;
124
- case Surface.ROTATION_270:
125
- degrees = 270;
126
- break;
127
- }
128
- facing = info.facing;
129
- if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
130
- displayOrientation = (info.orientation + degrees) % 360;
131
- displayOrientation = (360 - displayOrientation) % 360;
132
- } else {
133
- displayOrientation = (info.orientation - degrees + 360) % 360;
134
- }
135
-
136
- Log.d(TAG, "screen is rotated " + degrees + "deg from natural");
137
- Log.d(
138
- TAG,
139
- (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT ? "front" : "back") +
140
- " camera is oriented -" +
141
- info.orientation +
142
- "deg from natural"
143
- );
144
- Log.d(TAG, "need to rotate preview " + displayOrientation + "deg");
145
- mCamera.setDisplayOrientation(displayOrientation);
203
+ }
204
+
205
+ @Override
206
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
207
+ // We purposely disregard child measurements because act as a
208
+ // wrapper to a SurfaceView that centers the camera preview instead
209
+ // of stretching it.
210
+ final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
211
+ final int height = resolveSize(
212
+ getSuggestedMinimumHeight(),
213
+ heightMeasureSpec
214
+ );
215
+ setMeasuredDimension(width, height);
216
+
217
+ if (mSupportedPreviewSizes != null) {
218
+ mPreviewSize =
219
+ getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
146
220
  }
221
+ }
147
222
 
148
- public void switchCamera(Camera camera, int cameraId) {
149
- try {
150
- setCamera(camera, cameraId);
151
-
152
- Log.d("CameraPreview", "before set camera");
223
+ @Override
224
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
225
+ if (changed && getChildCount() > 0) {
226
+ final View child = getChildAt(0);
153
227
 
154
- View v;
155
- if (enableOpacity) {
156
- camera.setPreviewTexture(mSurface);
157
- v = mTextureView;
158
- } else {
159
- camera.setPreviewDisplay(mHolder);
160
- v = mSurfaceView;
161
- }
228
+ int width = r - l;
229
+ int height = b - t;
162
230
 
163
- Log.d("CameraPreview", "before getParameters");
231
+ int previewWidth = width;
232
+ int previewHeight = height;
164
233
 
165
- Camera.Parameters parameters = camera.getParameters();
234
+ if (mPreviewSize != null) {
235
+ previewWidth = mPreviewSize.width;
236
+ previewHeight = mPreviewSize.height;
166
237
 
167
- Log.d("CameraPreview", "before setPreviewSize");
168
-
169
- mSupportedPreviewSizes = parameters.getSupportedPreviewSizes();
170
- mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, v.getWidth(), v.getHeight());
171
- parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
172
- Log.d(TAG, mPreviewSize.width + " " + mPreviewSize.height);
173
-
174
- camera.setParameters(parameters);
175
- } catch (IOException exception) {
176
- Log.e(TAG, exception.getMessage());
238
+ if (displayOrientation == 90 || displayOrientation == 270) {
239
+ previewWidth = mPreviewSize.height;
240
+ previewHeight = mPreviewSize.width;
177
241
  }
178
- }
242
+ // LOG.d(TAG, "previewWidth:" + previewWidth + " previewHeight:" + previewHeight);
243
+ }
179
244
 
180
- @Override
181
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
182
- // We purposely disregard child measurements because act as a
183
- // wrapper to a SurfaceView that centers the camera preview instead
184
- // of stretching it.
185
- final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
186
- final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
187
- setMeasuredDimension(width, height);
245
+ int nW;
246
+ int nH;
247
+ int top;
248
+ int left;
188
249
 
189
- if (mSupportedPreviewSizes != null) {
190
- mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
191
- }
192
- }
250
+ float scale = 1.0f;
193
251
 
194
- @Override
195
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
196
- if (changed && getChildCount() > 0) {
197
- final View child = getChildAt(0);
198
-
199
- int width = r - l;
200
- int height = b - t;
201
-
202
- int previewWidth = width;
203
- int previewHeight = height;
204
-
205
- if (mPreviewSize != null) {
206
- previewWidth = mPreviewSize.width;
207
- previewHeight = mPreviewSize.height;
208
-
209
- if (displayOrientation == 90 || displayOrientation == 270) {
210
- previewWidth = mPreviewSize.height;
211
- previewHeight = mPreviewSize.width;
212
- }
213
- // LOG.d(TAG, "previewWidth:" + previewWidth + " previewHeight:" + previewHeight);
214
- }
215
-
216
- int nW;
217
- int nH;
218
- int top;
219
- int left;
220
-
221
- float scale = 1.0f;
222
-
223
- // Center the child SurfaceView within the parent.
224
- if (width * previewHeight < height * previewWidth) {
225
- Log.d(TAG, "center horizontally");
226
- int scaledChildWidth = (int) ((previewWidth * height / previewHeight) * scale);
227
- nW = (width + scaledChildWidth) / 2;
228
- nH = (int) (height * scale);
229
- top = 0;
230
- left = (width - scaledChildWidth) / 2;
231
- } else {
232
- Log.d(TAG, "center vertically");
233
- int scaledChildHeight = (int) ((previewHeight * width / previewWidth) * scale);
234
- nW = (int) (width * scale);
235
- nH = (height + scaledChildHeight) / 2;
236
- top = (height - scaledChildHeight) / 2;
237
- left = 0;
238
- }
239
- child.layout(left, top, nW, nH);
240
-
241
- Log.d("layout", "left:" + left);
242
- Log.d("layout", "top:" + top);
243
- Log.d("layout", "right:" + nW);
244
- Log.d("layout", "bottom:" + nH);
245
- }
252
+ // Center the child SurfaceView within the parent.
253
+ if (width * previewHeight < height * previewWidth) {
254
+ Log.d(TAG, "center horizontally");
255
+ int scaledChildWidth = (int) (
256
+ (previewWidth * height / previewHeight) * scale
257
+ );
258
+ nW = (width + scaledChildWidth) / 2;
259
+ nH = (int) (height * scale);
260
+ top = 0;
261
+ left = (width - scaledChildWidth) / 2;
262
+ } else {
263
+ Log.d(TAG, "center vertically");
264
+ int scaledChildHeight = (int) (
265
+ (previewHeight * width / previewWidth) * scale
266
+ );
267
+ nW = (int) (width * scale);
268
+ nH = (height + scaledChildHeight) / 2;
269
+ top = (height - scaledChildHeight) / 2;
270
+ left = 0;
271
+ }
272
+ child.layout(left, top, nW, nH);
273
+
274
+ Log.d("layout", "left:" + left);
275
+ Log.d("layout", "top:" + top);
276
+ Log.d("layout", "right:" + nW);
277
+ Log.d("layout", "bottom:" + nH);
246
278
  }
247
-
248
- public void surfaceCreated(SurfaceHolder holder) {
249
- // The Surface has been created, acquire the camera and tell it where
250
- // to draw.
251
- try {
252
- if (mCamera != null) {
253
- mSurfaceView.setWillNotDraw(false);
254
- mCamera.setPreviewDisplay(holder);
255
- }
256
- } catch (Exception exception) {
257
- Log.e(TAG, "Exception caused by setPreviewDisplay()", exception);
258
- }
279
+ }
280
+
281
+ public void surfaceCreated(SurfaceHolder holder) {
282
+ // The Surface has been created, acquire the camera and tell it where
283
+ // to draw.
284
+ try {
285
+ if (mCamera != null) {
286
+ mSurfaceView.setWillNotDraw(false);
287
+ mCamera.setPreviewDisplay(holder);
288
+ }
289
+ } catch (Exception exception) {
290
+ Log.e(TAG, "Exception caused by setPreviewDisplay()", exception);
259
291
  }
260
-
261
- public void surfaceDestroyed(SurfaceHolder holder) {
262
- // Surface will be destroyed when we return, so stop the preview.
263
- try {
264
- if (mCamera != null) {
265
- mCamera.stopPreview();
266
- }
267
- } catch (Exception exception) {
268
- Log.e(TAG, "Exception caused by surfaceDestroyed()", exception);
269
- }
292
+ }
293
+
294
+ public void surfaceDestroyed(SurfaceHolder holder) {
295
+ // Surface will be destroyed when we return, so stop the preview.
296
+ try {
297
+ if (mCamera != null) {
298
+ mCamera.stopPreview();
299
+ }
300
+ } catch (Exception exception) {
301
+ Log.e(TAG, "Exception caused by surfaceDestroyed()", exception);
270
302
  }
271
-
272
- private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
273
- final double ASPECT_TOLERANCE = 0.1;
274
- double targetRatio = (double) w / h;
275
- if (displayOrientation == 90 || displayOrientation == 270) {
276
- targetRatio = (double) h / w;
277
- }
278
-
279
- if (sizes == null) {
280
- return null;
281
- }
282
-
283
- Camera.Size optimalSize = null;
284
- double minDiff = Double.MAX_VALUE;
285
-
286
- int targetHeight = h;
287
-
288
- // Try to find an size match aspect ratio and size
289
- for (Camera.Size size : sizes) {
290
- double ratio = (double) size.width / size.height;
291
- if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
292
- if (Math.abs(size.height - targetHeight) < minDiff) {
293
- optimalSize = size;
294
- minDiff = Math.abs(size.height - targetHeight);
295
- }
296
- }
297
-
298
- // Cannot find the one match the aspect ratio, ignore the requirement
299
- if (optimalSize == null) {
300
- minDiff = Double.MAX_VALUE;
301
- for (Camera.Size size : sizes) {
302
- if (Math.abs(size.height - targetHeight) < minDiff) {
303
- optimalSize = size;
304
- minDiff = Math.abs(size.height - targetHeight);
305
- }
306
- }
307
- }
308
-
309
- Log.d(TAG, "optimal preview size: w: " + optimalSize.width + " h: " + optimalSize.height);
310
- return optimalSize;
303
+ }
304
+
305
+ private Camera.Size getOptimalPreviewSize(
306
+ List<Camera.Size> sizes,
307
+ int w,
308
+ int h
309
+ ) {
310
+ final double ASPECT_TOLERANCE = 0.1;
311
+ double targetRatio = (double) w / h;
312
+
313
+ int targetHeight = h;
314
+ if (displayOrientation == 90 || displayOrientation == 270) {
315
+ targetRatio = (double) h / w;
316
+ targetHeight = w;
311
317
  }
312
318
 
313
- public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
314
- if (mCamera != null) {
315
- try {
316
- // Now that the size is known, set up the camera parameters and begin
317
- // the preview.
318
- mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
319
- if (mSupportedPreviewSizes != null) {
320
- mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, w, h);
321
- }
322
- startCamera();
323
- } catch (Exception exception) {
324
- Log.e(TAG, "Exception caused by surfaceChanged()", exception);
325
- }
326
- }
319
+ if (sizes == null) {
320
+ return null;
327
321
  }
328
322
 
329
- private void startCamera() {
330
- Camera.Parameters parameters = mCamera.getParameters();
331
- parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
332
- requestLayout();
333
- //mCamera.setDisplayOrientation(90);
334
- mCamera.setParameters(parameters);
335
- mCamera.startPreview();
323
+ Camera.Size optimalSize = null;
324
+ double minDiff = Double.MAX_VALUE;
325
+
326
+ // Try to find an size match aspect ratio and size
327
+ for (Camera.Size size : sizes) {
328
+ double ratio = (double) size.width / size.height;
329
+ if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
330
+ if (Math.abs(size.height - targetHeight) < minDiff) {
331
+ optimalSize = size;
332
+ minDiff = Math.abs(size.height - targetHeight);
333
+ }
336
334
  }
337
335
 
338
- // Texture Callbacks
339
-
340
- public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
341
- // The Surface has been created, acquire the camera and tell it where
342
- // to draw.
343
- try {
344
- mSurface = surface;
345
- if (mSupportedPreviewSizes != null) {
346
- mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
347
- }
348
- if (mCamera != null) {
349
- mTextureView.setAlpha(opacity);
350
- mCamera.setPreviewTexture(surface);
351
- startCamera();
352
- }
353
- } catch (Exception exception) {
354
- Log.e(TAG, "Exception caused by onSurfaceTextureAvailable()", exception);
336
+ // Cannot find the one match the aspect ratio, ignore the requirement
337
+ if (optimalSize == null) {
338
+ minDiff = Double.MAX_VALUE;
339
+ for (Camera.Size size : sizes) {
340
+ if (Math.abs(size.height - targetHeight) < minDiff) {
341
+ optimalSize = size;
342
+ minDiff = Math.abs(size.height - targetHeight);
355
343
  }
344
+ }
356
345
  }
357
346
 
358
- public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {}
359
-
360
- public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
361
- try {
362
- if (mCamera != null) {
363
- mCamera.stopPreview();
364
- }
365
- } catch (Exception exception) {
366
- Log.e(TAG, "Exception caused by onSurfaceTextureDestroyed()", exception);
367
- return false;
347
+ Log.d(
348
+ TAG,
349
+ "optimal preview size: w: " +
350
+ optimalSize.width +
351
+ " h: " +
352
+ optimalSize.height
353
+ );
354
+ return optimalSize;
355
+ }
356
+
357
+ public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
358
+ if (mCamera != null) {
359
+ try {
360
+ // Now that the size is known, set up the camera parameters and begin
361
+ // the preview.
362
+ mSupportedPreviewSizes =
363
+ mCamera.getParameters().getSupportedPreviewSizes();
364
+ if (mSupportedPreviewSizes != null) {
365
+ mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, w, h);
368
366
  }
369
- return true;
367
+ startCamera();
368
+ } catch (Exception exception) {
369
+ Log.e(TAG, "Exception caused by surfaceChanged()", exception);
370
+ }
371
+ }
372
+ }
373
+
374
+ private void startCamera() {
375
+ Camera.Parameters parameters = mCamera.getParameters();
376
+ parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
377
+ requestLayout();
378
+ //mCamera.setDisplayOrientation(90);
379
+ mCamera.setParameters(parameters);
380
+ mCamera.startPreview();
381
+ }
382
+
383
+ // Texture Callbacks
384
+
385
+ public void onSurfaceTextureAvailable(
386
+ SurfaceTexture surface,
387
+ int width,
388
+ int height
389
+ ) {
390
+ // The Surface has been created, acquire the camera and tell it where
391
+ // to draw.
392
+ try {
393
+ mSurface = surface;
394
+ if (mSupportedPreviewSizes != null) {
395
+ mPreviewSize =
396
+ getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
397
+ }
398
+ if (mCamera != null) {
399
+ mTextureView.setAlpha(opacity);
400
+ mCamera.setPreviewTexture(surface);
401
+ startCamera();
402
+ }
403
+ } catch (Exception exception) {
404
+ Log.e(TAG, "Exception caused by onSurfaceTextureAvailable()", exception);
370
405
  }
406
+ }
407
+
408
+ public void onSurfaceTextureSizeChanged(
409
+ SurfaceTexture surface,
410
+ int width,
411
+ int height
412
+ ) {}
413
+
414
+ public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
415
+ try {
416
+ if (mCamera != null) {
417
+ mCamera.stopPreview();
418
+ }
419
+ } catch (Exception exception) {
420
+ Log.e(TAG, "Exception caused by onSurfaceTextureDestroyed()", exception);
421
+ return false;
422
+ }
423
+ return true;
424
+ }
371
425
 
372
- public void onSurfaceTextureUpdated(SurfaceTexture surface) {}
426
+ public void onSurfaceTextureUpdated(SurfaceTexture surface) {}
373
427
 
374
- public void setOneShotPreviewCallback(Camera.PreviewCallback callback) {
375
- if (mCamera != null) {
376
- mCamera.setOneShotPreviewCallback(callback);
377
- }
428
+ public void setOneShotPreviewCallback(Camera.PreviewCallback callback) {
429
+ if (mCamera != null) {
430
+ mCamera.setOneShotPreviewCallback(callback);
378
431
  }
432
+ }
379
433
 
380
- public void setOpacity(final float opacity) {
381
- this.opacity = opacity;
382
- if (mCamera != null && enableOpacity) {
383
- mTextureView.setAlpha(opacity);
384
- }
434
+ public void setOpacity(final float opacity) {
435
+ this.opacity = opacity;
436
+ if (mCamera != null && enableOpacity) {
437
+ mTextureView.setAlpha(opacity);
385
438
  }
439
+ }
386
440
  }