gpt4 book ai didi

android - 如何在 SurfaceView 上显示相机预览?

转载 作者:行者123 更新时间:2023-12-03 14:37:10 25 4
gpt4 key购买 nike

我正在尝试在 SurfaceView 上打开相机硬件。在布局中,我创建了一个 SurfaceView 并打开相机,如下面的代码所示。当我运行代码时,CameraAvailableCB 中的 toast 出现并显示“onCameraAvailable”,但 SurfaceView 上没有出现任何内容。

如何在 SurfaceView 上显示相机显示?

代码

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

this.mBtnCapture = (Button) findViewById(R.id.actMain_btn_capture);
this.mSurfaceView = (SurfaceView) findViewById(R.id.actMain_surfaceView);
this.mSurfaceHolder = this.mSurfaceView.getHolder();
this.mSurfaceHolder.addCallback(this);
this.mCameraManager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE);

try {
cameraIDsList = this.mCameraManager.getCameraIdList();

for (String id : cameraIDsList) {
Log.v(TAG, "CameraID: " + id);
}

} catch (CameraAccessException e) {
e.printStackTrace();
}

cameraStateCB = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice camera) {
Toast.makeText(getApplicationContext(), "onOpened", Toast.LENGTH_SHORT).show();

//requesting permission
int permissionCheck = ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {

if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.CAMERA)) {

} else {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CAMERA}, MY_PERMISSIONS_REQUEST_CAMERA);
Toast.makeText(getApplicationContext(), "request permission", Toast.LENGTH_SHORT).show();
}

} else {
Toast.makeText(getApplicationContext(), "PERMISSION_ALREADY_GRANTED", Toast.LENGTH_SHORT).show();
}

//opening the camera
try {
mCameraManager.openCamera(cameraIDsList[1], cameraStateCB, new Handler());

} catch (CameraAccessException e) {
e.printStackTrace();
}
}

@Override
public void onDisconnected(CameraDevice camera) {
Toast.makeText(getApplicationContext(), "onDisconnected", Toast.LENGTH_SHORT).show();
}

@Override
public void onError(CameraDevice camera, int error) {
Toast.makeText(getApplicationContext(), "onError", Toast.LENGTH_SHORT).show();
}
};

CameraManager.AvailabilityCallback cameraAvailableCB = new CameraManager.AvailabilityCallback() {
@Override
public void onCameraAvailable(String cameraId) {
super.onCameraAvailable(cameraId);

Toast.makeText(getApplicationContext(), "onCameraAvailable", Toast.LENGTH_SHORT).show();
}

@Override
public void onCameraUnavailable(String cameraId) {
super.onCameraUnavailable(cameraId);

Toast.makeText(getApplicationContext(), "onCameraUnavailable", Toast.LENGTH_SHORT).show();
}
};
this.mCameraManager.registerAvailabilityCallback(cameraAvailableCB, new Handler());
}



@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);

switch (requestCode) {
case MY_PERMISSIONS_REQUEST_CAMERA:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
// Open Camera
break;
}
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.w(TAG, "surfaceCreated");
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.w(TAG, "surfaceChanged");
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.w(TAG, "surfaceDestroyed");
}

最佳答案

要使用 Camera2 API 显示来自相机的预览,您应该执行以下步骤:

  • 获得使用相机设备的权限
  • 使用 CameraManager 打开与相机的连接
  • 已准备好 Surface 预览
  • 使用打开的相机设备和所需的表面(它不仅可以包括预览表面)创建 CaptureSession
  • CaptureSession 创建后,您需要创建和配置 CaptureRequest 并将其提交给 CaptureSession

  • 需要注意的是,准备表面和打开与相机的连接是独立的过程,因此您需要确保它们都在创建 CaptureSession 之前完成。

    这是在屏幕上显示相机预览的 Activity 示例:
    public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, Handler.Callback {
    static final String TAG = "CamTest";
    static final int MY_PERMISSIONS_REQUEST_CAMERA = 1242;
    private static final int MSG_CAMERA_OPENED = 1;
    private static final int MSG_SURFACE_READY = 2;
    private final Handler mHandler = new Handler(this);
    SurfaceView mSurfaceView;
    SurfaceHolder mSurfaceHolder;
    CameraManager mCameraManager;
    String[] mCameraIDsList;
    CameraDevice.StateCallback mCameraStateCB;
    CameraDevice mCameraDevice;
    CameraCaptureSession mCaptureSession;
    boolean mSurfaceCreated = true;
    boolean mIsCameraConfigured = false;
    private Surface mCameraSurface = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    this.mSurfaceView = (SurfaceView) findViewById(R.id.SurfaceViewPreview);
    this.mSurfaceHolder = this.mSurfaceView.getHolder();
    this.mSurfaceHolder.addCallback(this);
    this.mCameraManager = (CameraManager) this.getSystemService(Context.CAMERA_SERVICE);

    try {
    mCameraIDsList = this.mCameraManager.getCameraIdList();
    for (String id : mCameraIDsList) {
    Log.v(TAG, "CameraID: " + id);
    }
    } catch (CameraAccessException e) {
    e.printStackTrace();
    }

    mCameraStateCB = new CameraDevice.StateCallback() {
    @Override
    public void onOpened(CameraDevice camera) {
    Toast.makeText(getApplicationContext(), "onOpened", Toast.LENGTH_SHORT).show();

    mCameraDevice = camera;
    mHandler.sendEmptyMessage(MSG_CAMERA_OPENED);
    }

    @Override
    public void onDisconnected(CameraDevice camera) {
    Toast.makeText(getApplicationContext(), "onDisconnected", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onError(CameraDevice camera, int error) {
    Toast.makeText(getApplicationContext(), "onError", Toast.LENGTH_SHORT).show();
    }
    };
    }

    @Override
    protected void onStart() {
    super.onStart();

    //requesting permission
    int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
    if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {

    } else {
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, MY_PERMISSIONS_REQUEST_CAMERA);
    Toast.makeText(getApplicationContext(), "request permission", Toast.LENGTH_SHORT).show();
    }
    } else {
    Toast.makeText(getApplicationContext(), "PERMISSION_ALREADY_GRANTED", Toast.LENGTH_SHORT).show();
    try {
    mCameraManager.openCamera(mCameraIDsList[1], mCameraStateCB, new Handler());
    } catch (CameraAccessException e) {
    e.printStackTrace();
    }
    }
    }

    @Override
    protected void onStop() {
    super.onStop();
    try {
    if (mCaptureSession != null) {
    mCaptureSession.stopRepeating();
    mCaptureSession.close();
    mCaptureSession = null;
    }

    mIsCameraConfigured = false;
    } catch (final CameraAccessException e) {
    // Doesn't matter, cloising device anyway
    e.printStackTrace();
    } catch (final IllegalStateException e2) {
    // Doesn't matter, cloising device anyway
    e2.printStackTrace();
    } finally {
    if (mCameraDevice != null) {
    mCameraDevice.close();
    mCameraDevice = null;
    mCaptureSession = null;
    }
    }
    }

    @Override
    public boolean handleMessage(Message msg) {
    switch (msg.what) {
    case MSG_CAMERA_OPENED:
    case MSG_SURFACE_READY:
    // if both surface is created and camera device is opened
    // - ready to set up preview and other things
    if (mSurfaceCreated && (mCameraDevice != null)
    && !mIsCameraConfigured) {
    configureCamera();
    }
    break;
    }

    return true;
    }

    private void configureCamera() {
    // prepare list of surfaces to be used in capture requests
    List<Surface> sfl = new ArrayList<Surface>();

    sfl.add(mCameraSurface); // surface for viewfinder preview

    // configure camera with all the surfaces to be ever used
    try {
    mCameraDevice.createCaptureSession(sfl,
    new CaptureSessionListener(), null);
    } catch (CameraAccessException e) {
    e.printStackTrace();
    }

    mIsCameraConfigured = true;
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    switch (requestCode) {
    case MY_PERMISSIONS_REQUEST_CAMERA:
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED)
    try {
    mCameraManager.openCamera(mCameraIDsList[1], mCameraStateCB, new Handler());
    } catch (CameraAccessException e) {
    e.printStackTrace();
    }
    break;
    }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
    mCameraSurface = holder.getSurface();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    mCameraSurface = holder.getSurface();
    mSurfaceCreated = true;
    mHandler.sendEmptyMessage(MSG_SURFACE_READY);
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
    mSurfaceCreated = false;
    }

    private class CaptureSessionListener extends
    CameraCaptureSession.StateCallback {
    @Override
    public void onConfigureFailed(final CameraCaptureSession session) {
    Log.d(TAG, "CaptureSessionConfigure failed");
    }

    @Override
    public void onConfigured(final CameraCaptureSession session) {
    Log.d(TAG, "CaptureSessionConfigure onConfigured");
    mCaptureSession = session;

    try {
    CaptureRequest.Builder previewRequestBuilder = mCameraDevice
    .createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
    previewRequestBuilder.addTarget(mCameraSurface);
    mCaptureSession.setRepeatingRequest(previewRequestBuilder.build(),
    null, null);
    } catch (CameraAccessException e) {
    Log.d(TAG, "setting up preview failed");
    e.printStackTrace();
    }
    }
    }
    }

    关于android - 如何在 SurfaceView 上显示相机预览?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39893367/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com