diff --git a/samples/android/camera-preview/AndroidManifest.xml b/samples/android/camera-preview/AndroidManifest.xml index 8be9e9485e..5adf3a385f 100644 --- a/samples/android/camera-preview/AndroidManifest.xml +++ b/samples/android/camera-preview/AndroidManifest.xml @@ -3,9 +3,9 @@ android:versionCode="1" android:versionName="1.0" > - - - + + + @@ -14,7 +14,7 @@ android:label="@string/app_name" android:theme="@style/AppTheme" > diff --git a/samples/android/camera-preview/res/layout/activity_camera_writer.xml b/samples/android/camera-preview/res/layout/activity_camera_writer.xml index 2e27d58ad9..d31172176a 100644 --- a/samples/android/camera-preview/res/layout/activity_camera_writer.xml +++ b/samples/android/camera-preview/res/layout/activity_camera_writer.xml @@ -3,10 +3,10 @@ android:layout_width="match_parent" android:layout_height="match_parent" > - diff --git a/samples/android/camera-preview/src/org/opencv/test/camerawriter/OpenCvCameraBridgeViewBase.java b/samples/android/camera-preview/src/org/opencv/test/camerawriter/CameraViewBase.java similarity index 91% rename from samples/android/camera-preview/src/org/opencv/test/camerawriter/OpenCvCameraBridgeViewBase.java rename to samples/android/camera-preview/src/org/opencv/test/camerawriter/CameraViewBase.java index 0395cbd6e8..44effbfe50 100644 --- a/samples/android/camera-preview/src/org/opencv/test/camerawriter/OpenCvCameraBridgeViewBase.java +++ b/samples/android/camera-preview/src/org/opencv/test/camerawriter/CameraViewBase.java @@ -5,8 +5,6 @@ import java.util.List; import org.opencv.android.Utils; import org.opencv.core.Mat; import org.opencv.core.Size; -import org.opencv.highgui.Highgui; -import org.opencv.highgui.VideoCapture; import android.content.Context; import android.graphics.Bitmap; @@ -23,7 +21,7 @@ import android.view.SurfaceView; * frame to the screen. * The clients shall implement CvCameraViewListener */ -public abstract class OpenCvCameraBridgeViewBase extends SurfaceView implements SurfaceHolder.Callback { +public abstract class CameraViewBase extends SurfaceView implements SurfaceHolder.Callback { private static final int MAX_UNSPECIFIED = -1; @@ -36,8 +34,9 @@ public abstract class OpenCvCameraBridgeViewBase extends SurfaceView implements private Bitmap mCacheBitmap; - public OpenCvCameraBridgeViewBase(Context context, AttributeSet attrs) { + public CameraViewBase(Context context, AttributeSet attrs) { super(context,attrs); + Log.d(TAG, "call CameraViewBase constructor"); getHolder().addCallback(this); mMaxWidth = MAX_UNSPECIFIED; mMaxHeight = MAX_UNSPECIFIED; @@ -113,7 +112,7 @@ public abstract class OpenCvCameraBridgeViewBase extends SurfaceView implements /** * This method is provided for clients, so they can enable the camera connection. - * The actuall onCameraViewStarted callback will be delivered only after both this method is called and surface is available + * The actual onCameraViewStarted callback will be delivered only after both this method is called and surface is available */ public void enableView() { synchronized(mSyncObject) { @@ -124,7 +123,7 @@ public abstract class OpenCvCameraBridgeViewBase extends SurfaceView implements /** * This method is provided for clients, so they can disable camera connection and stop - * the delivery of frames eventhough the surfaceview itself is not destroyed and still stays on the scren + * the delivery of frames even though the surface view itself is not destroyed and still stays on the scren */ public void disableView() { synchronized(mSyncObject) { @@ -143,9 +142,9 @@ public abstract class OpenCvCameraBridgeViewBase extends SurfaceView implements * size - the biggest size which less or equal the size set will be selected. * As an example - we set setMaxFrameSize(200,200) and we have 176x152 and 320x240 sizes. The * preview frame will be selected with 176x152 size. - * This method is usefull when need to restrict the size of preview frame for some reason (for example for video recording) + * This method is useful when need to restrict the size of preview frame for some reason (for example for video recording) * @param maxWidth - the maximum width allowed for camera frame. - * @param maxHeight - the maxumum height allowed for camera frame + * @param maxHeight - the maximum height allowed for camera frame */ public void setMaxFrameSize(int maxWidth, int maxHeight) { mMaxWidth = maxWidth; @@ -212,7 +211,7 @@ public abstract class OpenCvCameraBridgeViewBase extends SurfaceView implements private void onEnterStartedState() { connectCamera(getWidth(), getHeight()); - /* Now create cahe Bitmap */ + /* Now create cache Bitmap */ mCacheBitmap = Bitmap.createBitmap(mFrameWidth, mFrameHeight, Bitmap.Config.ARGB_8888); } @@ -249,7 +248,8 @@ public abstract class OpenCvCameraBridgeViewBase extends SurfaceView implements if (mCacheBitmap != null) { Canvas canvas = getHolder().lockCanvas(); if (canvas != null) { - canvas.drawBitmap(mCacheBitmap, (canvas.getWidth() - mCacheBitmap.getWidth()) / 2, (canvas.getHeight() - mCacheBitmap.getHeight()) / 2, null); + canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR); + canvas.drawBitmap(mCacheBitmap, (canvas.getWidth() - mCacheBitmap.getWidth()) / 2, (canvas.getHeight() - mCacheBitmap.getHeight()) / 2, null); getHolder().unlockCanvasAndPost(canvas); } } diff --git a/samples/android/camera-preview/src/org/opencv/test/camerawriter/CameraWriterActivity.java b/samples/android/camera-preview/src/org/opencv/test/camerawriter/CameraWriterActivity.java deleted file mode 100644 index c6ffb2903d..0000000000 --- a/samples/android/camera-preview/src/org/opencv/test/camerawriter/CameraWriterActivity.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.opencv.test.camerawriter; - -import org.opencv.android.BaseLoaderCallback; -import org.opencv.android.LoaderCallbackInterface; -import org.opencv.android.OpenCVLoader; -import org.opencv.core.Mat; -import org.opencv.test.camerawriter.OpenCvCameraBridgeViewBase.CvCameraViewListener; - -import android.os.Bundle; -import android.app.Activity; -import android.util.Log; - -public class CameraWriterActivity extends Activity implements CvCameraViewListener { - - protected static final String TAG = "CameraWriterActivity"; - - - private OpenCvCameraBridgeViewBase mCameraView; - - - private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) { - @Override - public void onManagerConnected(int status) { - switch (status) { - case LoaderCallbackInterface.SUCCESS: - Log.i(TAG, "OpenCV loaded successfully"); - // Create and set View - mCameraView.setMaxFrameSize(640, 480); - mCameraView.enableView(); - break; - default: - super.onManagerConnected(status); - break; - } - } - }; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_camera_writer); - - mCameraView = (OpenCvCameraBridgeViewBase)findViewById(R.id.camera_surface_view); - mCameraView.setCvCameraViewListener(this); - OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mLoaderCallback); - - } - - public void onCameraViewStarted(int width, int height) { - // TODO Auto-generated method stub - - } - - public void onCameraViewStopped() { - // TODO Auto-generated method stub - - } - - public Mat onCameraFrame(Mat inputFrame) { - return inputFrame; - } -} diff --git a/samples/android/camera-preview/src/org/opencv/test/camerawriter/NativeCameraView.java b/samples/android/camera-preview/src/org/opencv/test/camerawriter/NativeCameraView.java new file mode 100644 index 0000000000..6bb39a48a3 --- /dev/null +++ b/samples/android/camera-preview/src/org/opencv/test/camerawriter/NativeCameraView.java @@ -0,0 +1,110 @@ +package org.opencv.test.camerawriter; + +import org.opencv.core.Mat; +import org.opencv.core.Size; +import org.opencv.highgui.Highgui; +import org.opencv.highgui.VideoCapture; + +import android.content.Context; +import android.util.AttributeSet; +import android.util.Log; + +/** + * This class is an implementation of a bridge between SurfaceView and native OpenCV camera. + * Due to the big amount of work done, by the base class this child is only responsible + * for creating camera, destroying camera and delivering frames while camera is enabled + */ +public class NativeCameraView extends CameraViewBase { + + public static final String TAG = "OpenCvNativeCameraView"; + private boolean mStopThread; + private Thread mThread; + private VideoCapture mCamera; + + + public NativeCameraView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + + @Override + protected void connectCamera(int width, int height) { + + /* 1. We need to instantiate camera + * 2. We need to start thread which will be getting frames + */ + /* First step - initialize camera connection */ + initializeCamera(getWidth(), getHeight()); + + /* now we can start update thread */ + mThread = new Thread(new CameraWorker()); + mThread.start(); + } + + @Override + protected void disconnectCamera() { + /* 1. We need to stop thread which updating the frames + * 2. Stop camera and release it + */ + try { + mStopThread = true; + mThread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + mThread = null; + mStopThread = false; + } + + /* Now release camera */ + releaseCamera(); + + } + + private void initializeCamera(int width, int height) { + mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID); + //TODO: improve error handling + + java.util.List sizes = mCamera.getSupportedPreviewSizes(); + + /* Select the size that fits surface considering maximum size allowed */ + Size frameSize = calculateCameraFrameSize(sizes, width, height); + + + double frameWidth = frameSize.width; + double frameHeight = frameSize.height; + + + mCamera.set(Highgui.CV_CAP_PROP_FRAME_WIDTH, frameWidth); + mCamera.set(Highgui.CV_CAP_PROP_FRAME_HEIGHT, frameHeight); + + mFrameWidth = (int)frameWidth; + mFrameHeight = (int)frameHeight; + + Log.i(TAG, "Selected camera frame size = (" + mFrameWidth + ", " + mFrameHeight + ")"); + } + + private void releaseCamera() { + if (mCamera != null) { + mCamera.release(); + } + } + + private class CameraWorker implements Runnable { + public void run() { + do { + if (!mCamera.grab()) { + Log.e(TAG, "Camera frame grab failed"); + break; + } + mCamera.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA); + + deliverAndDrawFrame(mRgba); + + } while (!mStopThread); + } + + private Mat mRgba = new Mat(); + } + +} diff --git a/samples/android/camera-preview/src/org/opencv/test/camerawriter/OpenCvNativeCameraView.java b/samples/android/camera-preview/src/org/opencv/test/camerawriter/OpenCvNativeCameraView.java deleted file mode 100644 index 5181b55256..0000000000 --- a/samples/android/camera-preview/src/org/opencv/test/camerawriter/OpenCvNativeCameraView.java +++ /dev/null @@ -1,125 +0,0 @@ -package org.opencv.test.camerawriter; - -import org.opencv.android.Utils; -import org.opencv.core.Mat; -import org.opencv.core.Size; -import org.opencv.highgui.Highgui; -import org.opencv.highgui.VideoCapture; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.util.AttributeSet; -import android.util.Log; - -/** - * This class is an implementation of a bridge between SurfaceView and native OpenCV camera. - * Due to the big amount of work done, by the base class this child is only responsible - * for creating camera, destroying camera and delivering frames while camera is enabled - */ -public class OpenCvNativeCameraView extends OpenCvCameraBridgeViewBase { - - public static final String TAG = "OpenCvNativeCameraView"; - private boolean mStopThread; - private Thread mThread; - private VideoCapture mCamera; - - - public OpenCvNativeCameraView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - - @Override - protected void connectCamera(int width, int height) { - - /* 1. We need to instantiate camera - * 2. We need to start thread which will be getting frames - */ - /* First step - initialize camera connection */ - initializeCamera(getWidth(), getHeight()); - - /* now we can start update thread */ - mThread = new Thread(new CameraWorker(getWidth(), getHeight())); - mThread.start(); - } - - @Override - protected void disconnectCamera() { - /* 1. We need to stop thread which updating the frames - * 2. Stop camera and release it - */ - try { - mStopThread = true; - mThread.join(); - } catch (InterruptedException e) { - e.printStackTrace(); - } finally { - mThread = null; - mStopThread = false; - } - - /* Now release camera */ - releaseCamera(); - - } - - private void initializeCamera(int width, int height) { - mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID); - //TODO: improve error handling - - java.util.List sizes = mCamera.getSupportedPreviewSizes(); - - /* Select the size that fits surface considering maximum size allowed */ - Size frameSize = calculateCameraFrameSize(sizes, width, height); - - - double frameWidth = frameSize.width; - double frameHeight = frameSize.height; - - - mCamera.set(Highgui.CV_CAP_PROP_FRAME_WIDTH, frameWidth); - mCamera.set(Highgui.CV_CAP_PROP_FRAME_HEIGHT, frameHeight); - - mFrameWidth = (int)frameWidth; - mFrameHeight = (int)frameHeight; - - Log.i(TAG, "Selected camera frame size = (" + mFrameWidth + ", " + mFrameHeight + ")"); - } - - private void releaseCamera() { - if (mCamera != null) { - mCamera.release(); - } - } - - private class CameraWorker implements Runnable { - - private Mat mRgba = new Mat(); - private int mWidth; - private int mHeight; - - CameraWorker(int w, int h) { - mWidth = w; - mHeight = h; - } - - public void run() { - Mat modified; - - - do { - if (!mCamera.grab()) { - Log.e(TAG, "Camera frame grab failed"); - break; - } - mCamera.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA); - - deliverAndDrawFrame(mRgba); - - } while (!mStopThread); - - } - } - -} diff --git a/samples/android/camera-preview/src/org/opencv/test/camerawriter/PreviewActivity.java b/samples/android/camera-preview/src/org/opencv/test/camerawriter/PreviewActivity.java new file mode 100644 index 0000000000..50b283fdf6 --- /dev/null +++ b/samples/android/camera-preview/src/org/opencv/test/camerawriter/PreviewActivity.java @@ -0,0 +1,60 @@ +package org.opencv.test.camerawriter; + +import org.opencv.android.BaseLoaderCallback; +import org.opencv.android.LoaderCallbackInterface; +import org.opencv.android.OpenCVLoader; +import org.opencv.core.Mat; +import org.opencv.test.camerawriter.CameraViewBase.CvCameraViewListener; + +import android.os.Bundle; +import android.app.Activity; +import android.util.Log; + +public class PreviewActivity extends Activity implements CvCameraViewListener { + + protected static final String TAG = "CameraWriterActivity"; + + private CameraViewBase mCameraView; + + private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) { + @Override + public void onManagerConnected(int status) { + switch (status) { + case LoaderCallbackInterface.SUCCESS: + Log.i(TAG, "OpenCV loaded successfully"); + // Create and set View + mCameraView.setMaxFrameSize(640, 480); + mCameraView.enableView(); + break; + default: + super.onManagerConnected(status); + break; + } + } + }; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_camera_writer); + + mCameraView = (CameraViewBase)findViewById(R.id.camera_surface_view); + mCameraView.setCvCameraViewListener(this); + OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_2, this, mLoaderCallback); + + } + + public void onCameraViewStarted(int width, int height) { + // TODO Auto-generated method stub + + } + + public void onCameraViewStopped() { + // TODO Auto-generated method stub + + } + + public Mat onCameraFrame(Mat inputFrame) { + return inputFrame; + } +}