Android预览相机未填充其FrameLayout

时间:2013-05-30 13:27:23

标签: android-layout opencv android-camera

我已经开始学习Android的东西,以开发一些应用程序。为此,我使用Eclipse Juno。然后,我还下载了Opencv4Android(在2.4.5版本中),以使用这些库的功能。我已经在Eclipse中导入了所有教程,我决定使用示例“cameracontrol”作为我的应用程序的基础。 现在,我遇到了一个问题:我在相机顶部的框架布局中找到了相机的预览。但框架布局以这种方式出现:相机预览周围有黑色边框,因为预览尺寸与框架布局不同,因此它们不匹配。

在相机控制中,在Tutorial3View类中,有一个允许更改预览分辨率的功能,因此应该可以将其调整为框架布局的大小,但是如果我插入onCreate()主要活动的方法,应用程序崩溃。 方法是:

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

因此,如果在OnCreate()方法中我尝试获取帧布局的宽度和高度,将其作为Size传递给setResolution,我的代码不起作用。

否则,我更倾向于将帧布局的大小调整为预览的大小,以免在预览中出现失真。

这是框架布局的xml代码:

<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>

我使用的教程是
this

本教程使用类org.opencv.android.JavaCameraView打开设备的摄像头。 我该怎么办?

我还想过,当它被捕获时,动态调整每一帧的大小。所以在onCameraFrame方法中,我调用了这个函数:

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

传递框架,其中frameLayout是预览的容器。我已经确认框架的宽度和高度值正确到达。 在这种情况下,我收到此错误:

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)

5 个答案:

答案 0 :(得分:2)

手动设置“CameraBridgeViewBase”类的变量“mScale”的值。就我而言,它等于1.0。如果它被设置为1.3,则相机被拉伸(结果是预览看起来有点变焦),因此移除了黑色边框。

答案 1 :(得分:1)

一般来说,opencv相机的比例是4:3。所以使用命令使操作栏和通知栏不可见

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

把它放在onCreate()和setContentView()之间。

这使得相机预览全屏..它对我有用:D

答案 2 :(得分:0)

  

这是一个允许更改预览分辨率的功能,因此应该可以根据帧布局的大小进行调整

不幸的是,生活并不像看起来那么容易。预览的分辨率可能会更改,但只能更改为相机的getSupportedPreviewSizes()返回的Size之一(请注意,前置和后置摄像头通常支持不同的列表)。

关于缩放,您可以这样做,但会导致预览图像失真。最佳解决方案是裁剪相机视图:

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

答案 3 :(得分:0)

我进入了CameraBridgeViewBase,进入了deliverAndDraw Frame函数,只是更改了canvas.drawBitmap函数的参数

  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);
          */
 } 

答案 4 :(得分:0)

您可以使用setMaxFrameSize()对象的CameraBridgeViewBase方法设置传入的帧大小。

只需在您的onCreate()方法中或在您将CameraBridgeViewBase对象初始化的任何地方进行调用,然后将其放入其中....

对我而言......

mOpenCvCameraView.setMaxFrameSize(720, 480);

请注意,720和480是我的设备的值,您可以根据想要填充FrameLayout来设置它。