Naming fixed;

Warnings fixed;
Nexus 7 support added to manifest.
pull/80/head
Alexander Smorkalov 12 years ago committed by Andrey Kamaev
parent cd152c3a03
commit cc3430dbcc
  1. 8
      samples/android/camera-preview/AndroidManifest.xml
  2. 8
      samples/android/camera-preview/res/layout/activity_camera_writer.xml
  3. 20
      samples/android/camera-preview/src/org/opencv/test/camerawriter/CameraViewBase.java
  4. 62
      samples/android/camera-preview/src/org/opencv/test/camerawriter/CameraWriterActivity.java
  5. 110
      samples/android/camera-preview/src/org/opencv/test/camerawriter/NativeCameraView.java
  6. 125
      samples/android/camera-preview/src/org/opencv/test/camerawriter/OpenCvNativeCameraView.java
  7. 60
      samples/android/camera-preview/src/org/opencv/test/camerawriter/PreviewActivity.java

@ -3,9 +3,9 @@
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.CAMERA" required="false"/>
<uses-feature android:name="android.hardware.camera" required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus" required="false"/>
<uses-sdk android:minSdkVersion="8" />
@ -14,7 +14,7 @@
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".CameraWriterActivity"
android:name=".PreviewActivity"
android:label="@string/title_activity_camera_writer" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

@ -3,10 +3,10 @@
android:layout_width="match_parent"
android:layout_height="match_parent" >
<view class="org.opencv.test.camerawriter.OpenCvNativeCameraView"
android:id="@+id/camera_surface_view"
android:layout_width = "fill_parent"
android:layout_height="fill_parent"
<view class="org.opencv.test.camerawriter.NativeCameraView"
android:id="@+id/camera_surface_view"
android:layout_width = "fill_parent"
android:layout_height="fill_parent"
/>

@ -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);
}
}

@ -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;
}
}

@ -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<Size> 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();
}
}

@ -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<Size> 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);
}
}
}

@ -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;
}
}
Loading…
Cancel
Save