在Fragment中创建相机预览

时间:2018-06-08 20:04:42

标签: android

我整天都在互联网上搜索,但我找不到任何可以解决我问题的方法:在应用程序运行时如何才能预览相机?我认为这并不困难,但我是一个初学者,我真的无法达到这一点。我使用的代码如下:

public class CameraConnectionFragment extends Fragment {
private static final Logger LOGGER = new Logger();
/**
* The camera preview size will be chosen to be the smallest frame by pixel  size capable of
* containing a DESIRED_SIZE x DESIRED_SIZE square.
*/
private static final int MINIMUM_PREVIEW_SIZE = 320;

/**
* Conversion from screen rotation to JPEG orientation.
*/
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
private static final String FRAGMENT_DIALOG = "dialog";
static {
ORIENTATIONS.append(Surface.ROTATION_0, 90);
ORIENTATIONS.append(Surface.ROTATION_90, 0);
ORIENTATIONS.append(Surface.ROTATION_180, 270);
ORIENTATIONS.append(Surface.ROTATION_270, 180);
}



/**
* {@link android.view.TextureView.SurfaceTextureListener} handles several  lifecycle events on a
* {@link TextureView}.
*/

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,   Bundle savedInstanceState) {
View view =  inflater.inflate(R.layout.camera_connection_fragment, container, false);
Button capture = (Button) view.findViewById(R.id.button);
Button preview = (Button) view.findViewById(R.id.button2);

preview.setOnClickListener(new View.OnClickListener() {


  public void onClick(View v) {

      //I WANT TO INSERT THE CODE FOR THE CAMERA PREVIEW HERE.

  }
});

  capture.setOnClickListener(new View.OnClickListener() {


      public void onClick(View v) {
          try {
              captureSession.capture(previewRequest, captureCallback, backgroundHandler);
          }
          catch (final CameraAccessException e) {
              LOGGER.e(e, "Exception!");
          }

      }
  });

return view;

}

xml文件camera_connection_fragment如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<org.tensorflow.demo.AutoFitTextureView
    android:id="@+id/texture"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true" />

<org.tensorflow.demo.RecognitionScoreView
    android:id="@+id/results"
    android:layout_width="match_parent"
    android:layout_height="198dp"
    android:layout_alignParentTop="true" />

<org.tensorflow.demo.OverlayView
    android:id="@+id/debug_overlay"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_alignParentStart="true"
    android:layout_alignParentTop="true" />

<Button
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentStart="true"
    android:layout_marginBottom="21dp"
    android:layout_marginStart="12dp"
    android:text="Capture" />

<Button
    android:id="@+id/button2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentEnd="true"
    android:layout_alignTop="@+id/button"
    android:layout_marginEnd="35dp"
    android:text="Preview" />

<SurfaceView
    android:id="@+id/surfaceView2"
    android:layout_width="wrap_content"
    android:layout_height="67dp"
    android:layout_alignBottom="@+id/button"
    android:layout_alignParentStart="true"
    android:layout_marginStart="134dp" />


</RelativeLayout>

我想将相机预览的代码放在

preview.setOnClickListener(new View.OnClickListener() {


public void onClick(View v) {

  //I WANT TO INSERT THE CODE FOR THE CAMERA PREVIEW HERE.

}
});

您对我应该如何实现这一点有任何想法吗?

1 个答案:

答案 0 :(得分:0)

我认为发布它作为答案更容易。从API 23开始,您需要在运行时请求权限。因此,如果您计划将设备定位到23及更高版本,则需要添加运行时权限检查以及Manifest权限。

对于预览,您需要查看方法createCameraPreviewSession,更准确地说是onConfigured回调:

mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),
                new CameraCaptureSession.StateCallback() {

                    @Override
                    public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
                        // The camera is already closed
                        if (null == mCameraDevice) {
                            return;
                        }

                        // When the session is ready, we start displaying the preview.
                        mCaptureSession = cameraCaptureSession;
                        try {
                            // Auto focus should be continuous for camera preview.
                            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                                    CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                            // Flash is automatically enabled when necessary.
                            setAutoFlash(mPreviewRequestBuilder);

                            // Finally, we start displaying the camera preview.
                            mPreviewRequest = mPreviewRequestBuilder.build();
                            mCaptureSession.setRepeatingRequest(mPreviewRequest,
                                    mCaptureCallback, mBackgroundHandler);
                        } catch (CameraAccessException e) {
                            e.printStackTrace();
                        }
                    }

                    @Override
                    public void onConfigureFailed(
                            @NonNull CameraCaptureSession cameraCaptureSession) {
                        showToast("Failed");
                    }
                }, null
        );

如您所见,mPreviewRequestmPreviewRequestBuilder用于设置预览。

修改

所以Camera2BasicFragment只是Fragment托管Surface和相机,因此当您运行该应用时,您可以直接看到预览。据我所知,你想要的是在预览之前有一个输入屏幕。

为方便起见,您可以构建应用程序,以便CameraConnectionFragment可以作为输入屏幕(您将有一个按钮来开始预览),然后将导致预览片段。

预览片段将是Camera2BasicFragment,您可以从存储库中复制它。因此,在onClick方法中,您将执行一个片段交易,引导您Camera2BasicFragment