@capacitor-community/camera-preview 3.0.0 → 3.1.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.
- package/README.md +2 -2
- package/android/src/androidTest/java/com/getcapacitor/android/ExampleInstrumentedTest.java +3 -3
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraActivity.java +835 -799
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java +184 -173
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CustomSurfaceView.java +12 -14
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CustomTextureView.java +16 -18
- package/android/src/main/java/com/ahm/capacitor/camera/preview/Preview.java +327 -323
- package/android/src/main/java/com/ahm/capacitor/camera/preview/TapGestureDetector.java +15 -14
- package/android/src/test/java/com/getcapacitor/ExampleUnitTest.java +4 -3
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/web.d.ts +2 -2
- package/dist/esm/web.js +24 -23
- package/dist/esm/web.js.map +1 -1
- package/ios/Plugin/CameraController.swift +106 -129
- package/ios/Plugin/Plugin.swift +76 -90
- package/ios/PluginTests/PluginTests.swift +8 -8
- package/package.json +27 -2
|
@@ -11,372 +11,376 @@ import android.view.SurfaceHolder;
|
|
|
11
11
|
import android.view.TextureView;
|
|
12
12
|
import android.view.View;
|
|
13
13
|
import android.widget.RelativeLayout;
|
|
14
|
-
|
|
15
14
|
import java.io.IOException;
|
|
16
15
|
import java.util.List;
|
|
17
16
|
|
|
18
|
-
class Preview extends RelativeLayout implements SurfaceHolder.Callback,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
Preview(Context context, boolean enableOpacity) {
|
|
42
|
-
super(context);
|
|
43
|
-
|
|
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();
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
public void setCamera(Camera camera, int cameraId) {
|
|
67
|
-
if (camera != null) {
|
|
68
|
-
mCamera = camera;
|
|
69
|
-
this.cameraId = cameraId;
|
|
70
|
-
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
|
|
71
|
-
setCameraDisplayOrientation();
|
|
72
|
-
|
|
73
|
-
List<String> mFocusModes = mCamera.getParameters().getSupportedFocusModes();
|
|
74
|
-
|
|
75
|
-
Camera.Parameters params = mCamera.getParameters();
|
|
76
|
-
if (mFocusModes.contains("continuous-picture")) {
|
|
77
|
-
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
|
|
78
|
-
} else if (mFocusModes.contains("continuous-video")){
|
|
79
|
-
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
|
|
80
|
-
} else if (mFocusModes.contains("auto")){
|
|
81
|
-
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
|
|
82
|
-
}
|
|
83
|
-
mCamera.setParameters(params);
|
|
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);
|
|
84
38
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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
|
+
}
|
|
102
62
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
case Surface.ROTATION_270:
|
|
124
|
-
degrees = 270;
|
|
125
|
-
break;
|
|
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
|
+
}
|
|
126
83
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
displayOrientation = (360 - displayOrientation) % 360;
|
|
131
|
-
} else {
|
|
132
|
-
displayOrientation = (info.orientation - degrees + 360) % 360;
|
|
84
|
+
|
|
85
|
+
public int getDisplayOrientation() {
|
|
86
|
+
return displayOrientation;
|
|
133
87
|
}
|
|
134
88
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
mCamera.setDisplayOrientation(displayOrientation);
|
|
139
|
-
}
|
|
89
|
+
public int getCameraFacing() {
|
|
90
|
+
return facing;
|
|
91
|
+
}
|
|
140
92
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
93
|
+
public void printPreviewSize(String from) {
|
|
94
|
+
Log.d(TAG, "printPreviewSize from " + from + ": > width: " + mPreviewSize.width + " height: " + mPreviewSize.height);
|
|
95
|
+
}
|
|
144
96
|
|
|
145
|
-
|
|
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
|
+
}
|
|
103
|
+
}
|
|
146
104
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
105
|
+
private 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
|
+
}
|
|
155
135
|
|
|
156
|
-
|
|
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);
|
|
146
|
+
}
|
|
157
147
|
|
|
158
|
-
|
|
148
|
+
public void switchCamera(Camera camera, int cameraId) {
|
|
149
|
+
try {
|
|
150
|
+
setCamera(camera, cameraId);
|
|
159
151
|
|
|
160
|
-
|
|
152
|
+
Log.d("CameraPreview", "before set camera");
|
|
161
153
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
154
|
+
View v;
|
|
155
|
+
if (enableOpacity) {
|
|
156
|
+
camera.setPreviewTexture(mSurface);
|
|
157
|
+
v = mTextureView;
|
|
158
|
+
} else {
|
|
159
|
+
camera.setPreviewDisplay(mHolder);
|
|
160
|
+
v = mSurfaceView;
|
|
161
|
+
}
|
|
166
162
|
|
|
167
|
-
|
|
168
|
-
} catch (IOException exception) {
|
|
169
|
-
Log.e(TAG, exception.getMessage());
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
@Override
|
|
174
|
-
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
175
|
-
// We purposely disregard child measurements because act as a
|
|
176
|
-
// wrapper to a SurfaceView that centers the camera preview instead
|
|
177
|
-
// of stretching it.
|
|
178
|
-
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
|
|
179
|
-
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
|
|
180
|
-
setMeasuredDimension(width, height);
|
|
181
|
-
|
|
182
|
-
if (mSupportedPreviewSizes != null) {
|
|
183
|
-
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
163
|
+
Log.d("CameraPreview", "before getParameters");
|
|
186
164
|
|
|
187
|
-
|
|
188
|
-
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
|
165
|
+
Camera.Parameters parameters = camera.getParameters();
|
|
189
166
|
|
|
190
|
-
|
|
191
|
-
final View child = getChildAt(0);
|
|
167
|
+
Log.d("CameraPreview", "before setPreviewSize");
|
|
192
168
|
|
|
193
|
-
|
|
194
|
-
|
|
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);
|
|
195
173
|
|
|
196
|
-
|
|
197
|
-
|
|
174
|
+
camera.setParameters(parameters);
|
|
175
|
+
} catch (IOException exception) {
|
|
176
|
+
Log.e(TAG, exception.getMessage());
|
|
177
|
+
}
|
|
178
|
+
}
|
|
198
179
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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);
|
|
202
188
|
|
|
203
|
-
if(
|
|
204
|
-
|
|
205
|
-
previewHeight = mPreviewSize.width;
|
|
189
|
+
if (mSupportedPreviewSizes != null) {
|
|
190
|
+
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
|
|
206
191
|
}
|
|
207
|
-
|
|
208
|
-
// LOG.d(TAG, "previewWidth:" + previewWidth + " previewHeight:" + previewHeight);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
int nW;
|
|
212
|
-
int nH;
|
|
213
|
-
int top;
|
|
214
|
-
int left;
|
|
215
|
-
|
|
216
|
-
float scale = 1.0f;
|
|
217
|
-
|
|
218
|
-
// Center the child SurfaceView within the parent.
|
|
219
|
-
if (width * previewHeight < height * previewWidth) {
|
|
220
|
-
Log.d(TAG, "center horizontally");
|
|
221
|
-
int scaledChildWidth = (int)((previewWidth * height / previewHeight) * scale);
|
|
222
|
-
nW = (width + scaledChildWidth) / 2;
|
|
223
|
-
nH = (int)(height * scale);
|
|
224
|
-
top = 0;
|
|
225
|
-
left = (width - scaledChildWidth) / 2;
|
|
226
|
-
} else {
|
|
227
|
-
Log.d(TAG, "center vertically");
|
|
228
|
-
int scaledChildHeight = (int) ((previewHeight * width / previewWidth) * scale);
|
|
229
|
-
nW = (int) (width * scale);
|
|
230
|
-
nH = (height + scaledChildHeight) / 2;
|
|
231
|
-
top = (height - scaledChildHeight) / 2;
|
|
232
|
-
left = 0;
|
|
233
|
-
}
|
|
234
|
-
child.layout(left, top, nW, nH);
|
|
235
|
-
|
|
236
|
-
Log.d("layout", "left:" + left);
|
|
237
|
-
Log.d("layout", "top:" + top);
|
|
238
|
-
Log.d("layout", "right:" + nW);
|
|
239
|
-
Log.d("layout", "bottom:" + nH);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
public void surfaceCreated(SurfaceHolder holder) {
|
|
244
|
-
// The Surface has been created, acquire the camera and tell it where
|
|
245
|
-
// to draw.
|
|
246
|
-
try {
|
|
247
|
-
if (mCamera != null) {
|
|
248
|
-
mSurfaceView.setWillNotDraw(false);
|
|
249
|
-
mCamera.setPreviewDisplay(holder);
|
|
250
|
-
}
|
|
251
|
-
} catch (Exception exception) {
|
|
252
|
-
Log.e(TAG, "Exception caused by setPreviewDisplay()", exception);
|
|
253
192
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
193
|
+
|
|
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
|
+
}
|
|
264
246
|
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
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
|
+
}
|
|
271
259
|
}
|
|
272
260
|
|
|
273
|
-
|
|
274
|
-
|
|
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
|
+
}
|
|
275
270
|
}
|
|
276
271
|
|
|
277
|
-
Camera.Size
|
|
278
|
-
|
|
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
|
+
}
|
|
279
278
|
|
|
280
|
-
|
|
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
|
+
}
|
|
281
297
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
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;
|
|
290
311
|
}
|
|
291
312
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
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
|
+
}
|
|
299
326
|
}
|
|
300
|
-
}
|
|
301
327
|
}
|
|
302
328
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
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();
|
|
336
|
+
}
|
|
306
337
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
//
|
|
311
|
-
//
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
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);
|
|
315
355
|
}
|
|
316
|
-
startCamera();
|
|
317
|
-
} catch (Exception exception) {
|
|
318
|
-
Log.e(TAG, "Exception caused by surfaceChanged()", exception);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
private void startCamera() {
|
|
324
|
-
Camera.Parameters parameters = mCamera.getParameters();
|
|
325
|
-
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
|
|
326
|
-
requestLayout();
|
|
327
|
-
//mCamera.setDisplayOrientation(90);
|
|
328
|
-
mCamera.setParameters(parameters);
|
|
329
|
-
mCamera.startPreview();
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
// Texture Callbacks
|
|
333
|
-
|
|
334
|
-
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
|
|
335
|
-
// The Surface has been created, acquire the camera and tell it where
|
|
336
|
-
// to draw.
|
|
337
|
-
try {
|
|
338
|
-
mSurface = surface;
|
|
339
|
-
if (mSupportedPreviewSizes != null) {
|
|
340
|
-
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
|
|
341
|
-
}
|
|
342
|
-
if (mCamera != null) {
|
|
343
|
-
mTextureView.setAlpha(opacity);
|
|
344
|
-
mCamera.setPreviewTexture(surface);
|
|
345
|
-
startCamera();
|
|
346
|
-
}
|
|
347
|
-
} catch (Exception exception) {
|
|
348
|
-
Log.e(TAG, "Exception caused by onSurfaceTextureAvailable()", exception);
|
|
349
356
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
357
|
+
|
|
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;
|
|
368
|
+
}
|
|
369
|
+
return true;
|
|
363
370
|
}
|
|
364
|
-
return true;
|
|
365
371
|
|
|
366
|
-
|
|
372
|
+
public void onSurfaceTextureUpdated(SurfaceTexture surface) {}
|
|
367
373
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
mCamera.setOneShotPreviewCallback(callback);
|
|
374
|
+
public void setOneShotPreviewCallback(Camera.PreviewCallback callback) {
|
|
375
|
+
if (mCamera != null) {
|
|
376
|
+
mCamera.setOneShotPreviewCallback(callback);
|
|
377
|
+
}
|
|
373
378
|
}
|
|
374
|
-
}
|
|
375
379
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
+
public void setOpacity(final float opacity) {
|
|
381
|
+
this.opacity = opacity;
|
|
382
|
+
if (mCamera != null && enableOpacity) {
|
|
383
|
+
mTextureView.setAlpha(opacity);
|
|
384
|
+
}
|
|
380
385
|
}
|
|
381
|
-
}
|
|
382
386
|
}
|