Android tutorial updated. HelloWorld sample ported on new framework.
authormikle <alexander.smorkalov@itseez.com>
Fri, 2 Nov 2012 12:27:26 +0000 (18:27 +0600)
committerAlexander Smorkalov <alexander.smorkalov@itseez.com>
Thu, 8 Nov 2012 10:51:42 +0000 (14:51 +0400)
doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.rst

index f7f0c47..52f7393 100644 (file)
@@ -270,105 +270,6 @@ It will be capable of accessing camera output, processing it and displaying the
 
 #. Set name, target, package and minSDKVersion accordingly.
 
-#. Create a new class (*File -> New -> Class*). Name it for example: *HelloOpenCVView*.
-
-   .. image:: images/dev_OCV_new_class.png
-        :alt: Add a new class.
-        :align: center
-
-   * It should extend *SurfaceView* class.
-   * It also should implement *SurfaceHolder.Callback*, *Runnable*.
-
-#. Edit *HelloOpenCVView* class.
-
-   * Add an *import* line for *android.content.context*.
-
-   * Modify autogenerated stubs: *HelloOpenCVView*, *surfaceCreated*, *surfaceDestroyed* and *surfaceChanged*.
-
-     .. code-block:: java
-        :linenos:
-
-        package com.hello.opencv.test;
-
-        import android.content.Context;
-
-        public class HelloOpenCVView extends SurfaceView implements Callback, Runnable {
-
-        public HelloOpenCVView(Context context) {
-            super(context);
-            getHolder().addCallback(this);
-        }
-
-        public void surfaceCreated(SurfaceHolder holder) {
-            (new Thread(this)).start();
-        }
-
-        public void surfaceDestroyed(SurfaceHolder holder) {
-            cameraRelease();
-        }
-
-        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
-            cameraSetup(width, height);
-        }
-
-        //...
-
-   * Add *cameraOpen*, *cameraRelease* and *cameraSetup* voids as shown below.
-
-   * Also, don't forget to add the public void *run()* as follows:
-
-     .. code-block:: java
-        :linenos:
-
-        public void run() {
-            // TODO: loop { getFrame(), processFrame(), drawFrame() }
-        }
-
-        public boolean cameraOpen() {
-            return false; //TODO: open camera
-        }
-
-        private void cameraRelease() {
-            // TODO release camera
-        }
-
-        private void cameraSetup(int width, int height) {
-            // TODO setup camera
-        }
-
-#. Create a new *Activity* (*New -> Other -> Android -> Android Activity*) and name it, for example: *HelloOpenCVActivity*. For this activity define *onCreate*, *onResume* and *onPause* voids.
-
-   .. code-block:: java
-      :linenos:
-
-       public void onCreate (Bundle savedInstanceState) {
-           super.onCreate(savedInstanceState);
-           mView = new HelloOpenCVView(this);
-           setContentView (mView);
-       }
-
-       protected void onPause() {
-           super.onPause();
-           mView.cameraRelease();
-       }
-
-       protected void onResume() {
-           super.onResume();
-           if( !mView.cameraOpen() ) {
-               // MessageBox and exit app
-               AlertDialog ad = new AlertDialog.Builder(this).create();
-               ad.setCancelable(false); // This blocks the "BACK" button
-               ad.setMessage("Fatal error: can't open camera!");
-               ad.setButton("OK", new DialogInterface.OnClickListener() {
-                   public void onClick(DialogInterface dialog, int which) {
-                       dialog.dismiss();
-                       finish();
-                   }
-               });
-               ad.show();
-           }
-       }
-
 #. Add the following permissions to the AndroidManifest.xml file:
 
    .. code-block:: xml
@@ -386,98 +287,90 @@ It will be capable of accessing camera output, processing it and displaying the
         :alt: Reference OpenCV library.
         :align: center
 
-#. We now need some code to handle the camera. Update the *HelloOpenCVView* class as follows:
+#. Create new view layout for your application, lets name it hello_opencv.xml, and add the following to it:
 
-   .. code-block:: java
-      :linenos:
+    .. code-block:: xml
+       :linenos:
 
-      private VideoCapture      mCamera;
-
-      public boolean cameraOpen() {
-          synchronized (this) {
-              cameraRelease();
-              mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID);
-              if (!mCamera.isOpened()) {
-                  mCamera.release();
-                  mCamera = null;
-                  Log.e("HelloOpenCVView", "Failed to open native camera");
-                  return false;
-              }
-          }
-          return true;
-      }
+       <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+           xmlns:tools="http://schemas.android.com/tools"
+           android:layout_width="match_parent"
+           android:layout_height="match_parent" >
 
-      public void cameraRelease() {
-          synchronized(this) {
-              if (mCamera != null) {
-                   mCamera.release();
-                   mCamera = null;
-              }
-          }
-      }
+           <org.opencv.android.JavaCameraView
+               android:layout_width="fill_parent"
+               android:layout_height="fill_parent"
+               android:visibility="gone"
+               android:id="@+id/java_surface_view" />
 
-      private void cameraSetup(int width, int height) {
-          synchronized (this) {
-              if (mCamera != null && mCamera.isOpened()) {
-                  List<Size> sizes = mCamera.getSupportedPreviewSizes();
-                  int mFrameWidth = width;
-                  int mFrameHeight = height;
-                  { // selecting optimal camera preview size
-                       double minDiff = Double.MAX_VALUE;
-                       for (Size size : sizes) {
-                           if (Math.abs(size.height - height) < minDiff) {
-                               mFrameWidth = (int) size.width;
-                               mFrameHeight = (int) size.height;
-                               minDiff = Math.abs(size.height - height);
-                           }
-                       }
-                   }
-                   mCamera.set(Highgui.CV_CAP_PROP_FRAME_WIDTH, mFrameWidth);
-                   mCamera.set(Highgui.CV_CAP_PROP_FRAME_HEIGHT, mFrameHeight);
-              }
-          }
-      }
+       </LinearLayout>
+
+#. Remove default auto generated layout, if exists.
 
-#. The last step would be to update the *run()* void in *HelloOpenCVView* class as follows:
+#. Create a new *Activity* (*New -> Other -> Android -> Android Activity*) and name it, for example: *HelloOpenCVActivity*. Add *CvCameraViewListener* interface to *implementes* section of *HelloOpenCVActivity* class. Add the following code to activity implementation:
 
    .. code-block:: java
       :linenos:
 
-      public void run() {
-          while (true) {
-              Bitmap bmp = null;
-              synchronized (this) {
-                  if (mCamera == null)
-                      break;
-                  if (!mCamera.grab())
-                      break;
-
-                  bmp = processFrame(mCamera);
-              }
-              if (bmp != null) {
-                  Canvas canvas = getHolder().lockCanvas();
-                  if (canvas != null) {
-                      canvas.drawBitmap(bmp, (canvas.getWidth()  - bmp.getWidth())  / 2,
-                                             (canvas.getHeight() - bmp.getHeight()) / 2, null);
-                      getHolder().unlockCanvasAndPost(canvas);
-
-                  }
-                  bmp.recycle();
-              }
-          }
-      }
+    public class Sample1Java extends Activity implements CvCameraViewListener {
+    
+        private CameraBridgeViewBase mOpenCvCameraView;
+
+        private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
+            @Override
+            public void onManagerConnected(int status) {
+                switch (status) {
+                    case LoaderCallbackInterface.SUCCESS: {
+                        Log.i(TAG, "OpenCV loaded successfully");
+                        mOpenCvCameraView.enableView();
+                    } break;
+                    default:
+                        super.onManagerConnected(status);
+               }
+            }
+        };
+
+        /** Called when the activity is first created. */
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            Log.i(TAG, "called onCreate");
+            super.onCreate(savedInstanceState);
+            requestWindowFeature(Window.FEATURE_NO_TITLE);
+            getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+            setContentView(R.layout.hello_opencv);
+            mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.java_surface_view);
+            mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
+            mOpenCvCameraView.setCvCameraViewListener(this);
+        }
 
-      protected Bitmap processFrame(VideoCapture capture) {
-          Mat mRgba = new Mat();
-          capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA);
-          //process mRgba
-          Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);
-          try {
-              Utils.matToBitmap(mRgba, bmp);
-          } catch(Exception e) {
-              Log.e("processFrame", "Utils.matToBitmap() throws an exception: " + e.getMessage());
-              bmp.recycle();
-              bmp = null;
-          }
-          return bmp;
-      }
+        @Override
+        public void onPause()
+        {
+            if (mOpenCvCameraView != null)
+                 mOpenCvCameraView.disableView();
+            super.onPause();
+        }
+
+        @Override
+        public void onResume()
+        {
+            super.onResume();
+            OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
+        }
+
+        public void onDestroy() {
+             super.onDestroy();
+             if (mOpenCvCameraView != null)
+                 mOpenCvCameraView.disableView();
+        }
+
+        public void onCameraViewStarted(int width, int height) {
+        }
+
+        public void onCameraViewStopped() {
+        }
+
+        public Mat onCameraFrame(Mat inputFrame) {
+            return inputFrame;
+        }
+    }