user140888
user140888

Reputation: 609

Android Preview Camera doesn't fill its FrameLayout

I have started to study something of Android, in order to develop some applications. For this purpose, I use Eclipse Juno. Then, I have also downloaded Opencv4Android (in the 2.4.5 version), to use functionalities of these libraries. I have imported all the tutorials in Eclipse, and I have decided to use the sample "cameracontrol" as base for my app. Now, I have a problem: I have located the preview of camera within a frame layout at the top of the interface. But the frame layout appears in this way: there are black borders around the camera preview because the preview size is different from that of frame layout, so they don't match.

In camera control, in the class Tutorial3View, there's a function that allows the change of the resolution of the preview, so it should be possible to adapt this to the size of frame layout, but if I insert in the onCreate() method of the main activity, the app crashes. The method is:

public void setResolution(Size resolution) {
    disconnectCamera();
    mMaxHeight = resolution.height;
    mMaxWidth = resolution.width;
    connectCamera(getWidth(), getHeight());
}

So if in OnCreate() method I try to obtain frame layout width and height, to pass this as Size to setResolution, my code doesn't work.

Otherwise, I'd prefer to adapt the size of frame layout to that of preview, in order not to have distortion in the preview.

This is the xml code of the frame layout:

<FrameLayout
    android:id="@+id/frame_capture"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:visibility="visible"
    android:clickable="false" android:foregroundGravity="fill"      android:layout_weight="0.7"
    android:layout_gravity="top">
    <com.micaela.myapp.MyView
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:id="@+id/HelloOpenCvView"
            android:visibility="gone"
            opencv:show_fps="true"
        />
    <ImageButton
            android:layout_width="51dp"
            android:layout_height="43dp"
            android:id="@+id/imageButton"
            android:layout_gravity="bottom|left"
            android:src="@drawable/switch_cam"
            android:background="#FF000000" android:cropToPadding="false" android:scaleType="centerCrop"/>
 </FrameLayout>

The tutorial I have used is
this

and this tutorial uses the class org.opencv.android.JavaCameraView to open the camera of device. How can I do?

I have also thought to adapt the size of every single frame on the fly, when it's captured. So in the method onCameraFrame, I call this function:

public void manageSize(Mat matrix){
    size = new org.opencv.core.Size(frameLayout.getMeasuredWidth(),frameLayout.getMeasuredHeight());
    Log.i(TAG,"ciao "+frameLayout.getMeasuredHeight());
    Log.i(TAG,"ciao "+frameLayout.getMeasuredWidth());
    Log.i(TAG,"prova "+size); //arrivano perfettamente i valori.
    Imgproc.resize(matrix,matrix,size);
}

passing the frame and where frameLayout is the container of the preview. I have verified that values of width and height of the frame arrive correctly. In this case, I get this error:

05-31 11:34:47.548: ERROR/cv::error()(17253): OpenCV Error: Assertion failed (src.dims == 2 && info.height == (uint32_t)src.rows && info.width == (uint32_t)src.cols) in void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong, jobject, jboolean), file /home/reports/ci/slave/50-SDK/opencv/modules/java/generator/src/cpp/utils.cpp, line 97
05-31 11:34:47.548: ERROR/org.opencv.android.Utils(17253): nMatToBitmap catched cv::Exception: /home/reports/ci/slave/50-SDK/opencv/modules/java/generator/src/cpp/utils.cpp:97: error: (-215) src.dims == 2 && info.height == (uint32_t)src.rows && info.width == (uint32_t)src.cols in function void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong, jobject, jboolean)
05-31 11:34:47.548: ERROR/CameraBridge(17253): Mat type: Mat [ 1013*1050*CV_8UC4, isCont=true, isSubmat=false, nativeObj=0x70b0c4b0, dataAddr=0x74f6d010 ]
05-31 11:34:47.548: ERROR/CameraBridge(17253): Bitmap type: 960*720
05-31 11:34:47.548: ERROR/CameraBridge(17253): Utils.matToBitmap() throws an exception: /home/reports/ci/slave/50-SDK/opencv/modules/java/generator/src/cpp/utils.cpp:97: error: (-215) src.dims == 2 && info.height == (uint32_t)src.rows && info.width == (uint32_t)src.cols in function void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong, jobject, jboolean)

Upvotes: 2

Views: 3920

Answers (5)

Azrael
Azrael

Reputation: 1

You can use the setMaxFrameSize() method of your CameraBridgeViewBase object to set the incoming frame size.

Just call it in your onCreate() method or wherever you have intialized your CameraBridgeViewBase object and put this after that....

For me it was..

mOpenCvCameraView.setMaxFrameSize(720, 480);

Note that 720 and 480 are the values for my device, you can set it as you want to fill the FrameLayout.

Upvotes: 0

Airman00
Airman00

Reputation: 336

I went into CameraBridgeViewBase, into the deliverAndDraw Frame function and just changed the parameters of the canvas.drawBitmap function

  if (mScale != 0) {
            // My new parameters for drawBitmap:
                canvas.drawBitmap(mCacheBitmap, new Rect(0,0,mCacheBitmap.getWidth(), mCacheBitmap.getHeight()),
                        new Rect(0,0,canvas.getWidth(),canvas.getHeight()) ,null);

    // I commented out the lines below
   /*         canvas.drawBitmap(mCacheBitmap, new Rect(0,0,mCacheBitmap.getWidth(), mCacheBitmap.getHeight()),
                     new Rect((int)((canvas.getWidth() - mScale*mCacheBitmap.getWidth()) / 2), //0
                     (int)((canvas.getHeight() - mScale*mCacheBitmap.getHeight()) / 2), //0
                     (int)((canvas.getWidth() - mScale*mCacheBitmap.getWidth()) / 2 + mScale*mCacheBitmap.getWidth()),
                     (int)((canvas.getHeight() - mScale*mCacheBitmap.getHeight()) / 2 + mScale*mCacheBitmap.getHeight())), null);
          */
 } 

Upvotes: 0

Alex Cohn
Alex Cohn

Reputation: 57203

there's a function that allows the change of the resolution of the preview, so it should be possible to adapt this to the size of frame layout

Unfortunately, the life is not as easy as it seems. The resolution of the preview may be changed, but only to one of the Sizes returned by getSupportedPreviewSizes() for your camera (note that front-facong and rear-facing cameras often support different lists).

Regarding scaling, you can do that but it causes distortion of the preview image. The best solution is to crop the camera view:

HelloOpenCvView.setX(-0.5*(HelloOpenCvView.get width()-screenWidth))

Upvotes: 0

Lakeesh Anand AN
Lakeesh Anand AN

Reputation: 151

Generally opencv camera is 4:3 ratio.so make the action bar and notifcation bar invisible using commands

requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

put this inbetween onCreate() and setContentView().

This makes camera preview fullscreen..It works for me :D

Upvotes: 2

user140888
user140888

Reputation: 609

Solved setting manually the value of the variable "mScale" of the class "CameraBridgeViewBase". In my case, it was equal to 1.0. If it is setted to 1.3, camera is stretched (the result is that preview seems to be a little zoomed) so removing that black borders.

Upvotes: 2

Related Questions