1 | package org.opencv.samples.tutorial3;
|
2 |
|
3 | import java.io.IOException;
|
4 | import java.util.List;
|
5 |
|
6 | import android.content.Context;
|
7 | import android.graphics.Bitmap;
|
8 | import android.graphics.Canvas;
|
9 | import android.graphics.ImageFormat;
|
10 |
|
11 | import android.hardware.Camera;
|
12 | import android.hardware.Camera.PreviewCallback;
|
13 | import android.os.Build;
|
14 | import android.util.Log;
|
15 | import android.view.SurfaceHolder;
|
16 | import android.view.SurfaceView;
|
17 |
|
18 | public abstract class SampleViewBase extends SurfaceView implements SurfaceHolder.Callback, Runnable {
|
19 | private static final String TAG = "Sample::SurfaceView";
|
20 |
|
21 | private int numberOfCameras;
|
22 | private Camera mCamera;
|
23 | private SurfaceHolder mHolder;
|
24 | private int mFrameWidth;
|
25 | private int mFrameHeight;
|
26 | private byte[] mFrame;
|
27 | private boolean mThreadRun;
|
28 | private byte[] mBuffer;
|
29 |
|
30 |
|
31 | public SampleViewBase(Context context) {
|
32 | super(context);
|
33 | mHolder = getHolder();
|
34 | mHolder.addCallback(this);
|
35 | Log.i(TAG, "Instantiated new " + this.getClass());
|
36 | }
|
37 |
|
38 | public int getFrameWidth() {
|
39 | return mFrameWidth;
|
40 | }
|
41 |
|
42 | public int getFrameHeight() {
|
43 | return mFrameHeight;
|
44 | }
|
45 |
|
46 | public void setPreview() throws IOException {
|
47 | |
48 | mCamera.setPreviewTexture( new SurfaceTexture(10) );
|
49 | else
|
50 | mCamera.setPreviewDisplay(null);*/
|
51 | }
|
52 |
|
53 | public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) {
|
54 | Log.i(TAG, "surfaceCreated");
|
55 | if (mCamera != null) {
|
56 | Camera.Parameters params = mCamera.getParameters();
|
57 |
|
58 | mFrameWidth = 352;
|
59 | mFrameHeight = 288;
|
60 |
|
61 |
|
62 | |
63 | int minDiff = Integer.MAX_VALUE;
|
64 | for (Camera.Size size : sizes) {
|
65 | if (Math.abs(size.height - height) < minDiff) {
|
66 | mFrameWidth = size.width;
|
67 | mFrameHeight = size.height;
|
68 | minDiff = Math.abs(size.height - height);
|
69 | }
|
70 | }
|
71 | }*/
|
72 |
|
73 | params.setPreviewSize(getFrameWidth(), getFrameHeight());
|
74 |
|
75 | List<String> FocusModes = params.getSupportedFocusModes();
|
76 | if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
|
77 | {
|
78 | params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
|
79 | }
|
80 |
|
81 | mCamera.setParameters(params);
|
82 |
|
83 |
|
84 | params = mCamera.getParameters();
|
85 | int size = params.getPreviewSize().width * params.getPreviewSize().height;
|
86 | size = size * ImageFormat.getBitsPerPixel(params.getPreviewFormat()) / 8;
|
87 | mBuffer = new byte[size];
|
88 |
|
89 | mFrame = new byte [size];
|
90 | mCamera.addCallbackBuffer(mBuffer);
|
91 |
|
92 | try {
|
93 | setPreview();
|
94 | } catch (IOException e) {
|
95 | Log.e(TAG, "mCamera.setPreviewDisplay/setPreviewTexture fails: " + e);
|
96 | }
|
97 |
|
98 |
|
99 | onPreviewStared(params.getPreviewSize().width, params.getPreviewSize().height);
|
100 |
|
101 |
|
102 | mCamera.startPreview();
|
103 | }
|
104 | }
|
105 |
|
106 | public void surfaceCreated(SurfaceHolder holder) {
|
107 | Log.i(TAG, "surfaceCreated");
|
108 | int cameraCount = 0;
|
109 | boolean flag1 = true;
|
110 | Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
|
111 | cameraCount = Camera.getNumberOfCameras();
|
112 | for ( int camIdx = 0; camIdx < cameraCount; camIdx++ ) {
|
113 | Camera.getCameraInfo( camIdx, cameraInfo );
|
114 | if ( cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT )
|
115 | {
|
116 | try {
|
117 | mCamera = Camera.open( camIdx );
|
118 | flag1 = false;
|
119 | } catch (RuntimeException e) {
|
120 | Log.e(TAG, "Camera failed to open: " + e.getLocalizedMessage());
|
121 | }
|
122 | }
|
123 | }
|
124 | if (flag1){ mCamera = Camera.open();}
|
125 |
|
126 | mCamera.setPreviewCallbackWithBuffer(new PreviewCallback() {
|
127 | public void onPreviewFrame(byte[] data, Camera camera) {
|
128 | synchronized (SampleViewBase.this) {
|
129 | System.arraycopy(data, 0, mFrame, 0, data.length);
|
130 | SampleViewBase.this.notify();
|
131 | }
|
132 | camera.addCallbackBuffer(mBuffer);
|
133 | }
|
134 | });
|
135 |
|
136 | (new Thread(this)).start();
|
137 | }
|
138 |
|
139 | public void surfaceDestroyed(SurfaceHolder holder) {
|
140 | Log.i(TAG, "surfaceDestroyed");
|
141 | mThreadRun = false;
|
142 | if (mCamera != null) {
|
143 | synchronized (this) {
|
144 | mCamera.stopPreview();
|
145 | mCamera.setPreviewCallback(null);
|
146 | mCamera.release();
|
147 | mCamera = null;
|
148 | }
|
149 | }
|
150 | onPreviewStopped();
|
151 | }
|
152 |
|
153 |
|
154 | protected abstract Bitmap processFrame(byte[] data);
|
155 |
|
156 | |
157 | * This method is called when the preview process is being started. It is called before the first frame delivered and processFrame is called
|
158 | * It is called with the width and height parameters of the preview process. It can be used to prepare the data needed during the frame processing.
|
159 | * @param previewWidth - the width of the preview frames that will be delivered via processFrame
|
160 | * @param previewHeight - the height of the preview frames that will be delivered via processFrame
|
161 | */
|
162 | protected abstract void onPreviewStared(int previewWidtd, int previewHeight);
|
163 |
|
164 | |
165 | * This method is called when preview is stopped. When this method is called the preview stopped and all the processing of frames already completed.
|
166 | * If the Bitmap object returned via processFrame is cached - it is a good time to recycle it.
|
167 | * Any other resourcses used during the preview can be released.
|
168 | */
|
169 | protected abstract void onPreviewStopped();
|
170 |
|
171 | public void run() {
|
172 | mThreadRun = true;
|
173 | Log.i(TAG, "Starting processing thread");
|
174 | while (mThreadRun) {
|
175 | Bitmap bmp = null;
|
176 |
|
177 | synchronized (this) {
|
178 | try {
|
179 | this.wait();
|
180 | bmp = processFrame(mFrame);
|
181 | } catch (InterruptedException e) {
|
182 | e.printStackTrace();
|
183 | }
|
184 | }
|
185 |
|
186 | if (bmp != null) {
|
187 | Canvas canvas = mHolder.lockCanvas();
|
188 | if (canvas != null) {
|
189 | canvas.drawBitmap(bmp, (canvas.getWidth() - getFrameWidth()) / 2, (canvas.getHeight() - getFrameHeight()) / 2, null);
|
190 | mHolder.unlockCanvasAndPost(canvas);
|
191 | }
|
192 | }
|
193 | }
|
194 | }
|
195 | } |