【问题标题】:How do I open the "front camera" on the Android platform?如何在安卓平台打开“前置摄像头”?
【发布时间】:2011-02-16 06:21:58
【问题描述】:

更一般地说,如果设备有多个嵌入式摄像头, 有没有办法特别初始化其中一个?

我在 Android 参考文档中没有找到它:

三星 SHW-M100S 有两个摄像头。如果没有提到使用两个摄像头,你知道三星是怎么做到的吗……?

【问题讨论】:

标签: android camera android-camera


【解决方案1】:

从 Android 2.1 开始,Android 在其 SDK 中仅支持单个摄像头。这很可能会在未来的 Android 版本中添加。

【讨论】:

  • 此声明对 Android 2.2 也有效?
  • @ozmank:是的,直到 Android 2.3 才添加多摄像头支持。
【解决方案2】:
public void surfaceCreated(SurfaceHolder holder) {
    try {
        mCamera = Camera.open();
        mCamera.setDisplayOrientation(90);
        mCamera.setPreviewDisplay(holder);

        Camera.Parameters p = mCamera.getParameters();
        p.set("camera-id",2);
        mCamera.setParameters(p);   
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

【讨论】:

  • 在 Galaxy S 上工作良好 重要的“camera-id”不是“camera_id”
  • 永远不要假设 90 度会让你得到正确的肖像旋转。它在许多设备上有所不同。
【解决方案3】:

随着Android 2.3 (Gingerbread) 的发布,您现在可以使用android.hardware.Camera 类来获取摄像头的数量、特定摄像头的相关信息以及对特定Camera 的引用。查看新的Camera API here

【讨论】:

    【解决方案4】:
    private Camera openFrontFacingCameraGingerbread() {
        int cameraCount = 0;
        Camera cam = null;
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        cameraCount = Camera.getNumberOfCameras();
        for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
            Camera.getCameraInfo(camIdx, cameraInfo);
            if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                try {
                    cam = Camera.open(camIdx);
                } catch (RuntimeException e) {
                    Log.e(TAG, "Camera failed to open: " + e.getLocalizedMessage());
                }
            }
        }
    
        return cam;
    }
    

    AndroidManifest.xml文件中添加以下权限:

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" android:required="false" />
    <uses-feature android:name="android.hardware.camera.front" android:required="false" />
    

    注意:此功能在 Gingerbread(2.3) 及以上 Android 版本中可用。

    【讨论】:

    • 是否可以通过Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 技术以某种方式使用它来打开现有的相机应用程序?
    • @loeschg Intent 以自己的方式处理相机动作。当您使用SurfaceView 来利用相机功能时,会使用此技术。
    • 这就是我的想法。谢谢!
    • 非常酷的帖子。我花了一段时间才发现相机朝向不一定与相机索引相同。例如,我的平板电脑只有一个摄像头(索引:0)但面向前方(面对索引:1)。因此使用像 Camera.open(CameraInfo.CAMERA_FACING_FRONT) 这样的简单代码是没有意义的。
    • @Matthias 同意你的观点。由于我们有不同的 OEM,我们的编程技术会根据我们的需要进行更改。感谢您强调。
    【解决方案5】:
    Camera camera;   
    if (Camera.getNumberOfCameras() >= 2) {
    
        //if you want to open front facing camera use this line   
        camera = Camera.open(CameraInfo.CAMERA_FACING_FRONT);
    
        //if you want to use the back facing camera
        camera = Camera.open(CameraInfo.CAMERA_FACING_BACK);                
    }
    
    try {
        camera.setPreviewDisplay("your surface holder here");
        camera.startPreview();      
    } catch (Exception e) {  
        camera.release();
    }
    

    /* 这不是正确的方法,这是运行 Android 4.0 或更早版本的旧设备的解决方案。这可以用于测试目的,但不推荐用于主要开发。此解决方案只能被视为临时解决方案。但是这个解决方案帮助了很多人,所以我不打算删除这个答案*/

    【讨论】:

    • 我认为它没有记录在案的用法。 open(int id) 接受 id,而不是相机位置
    • 请删除这个误导性的答案
    • @AmalanDhananjayan:例如参见@Matthias above 的评论:……我花了一段时间才发现摄像头朝向不一定与摄像头索引相同。例如,我的平板电脑只有一个摄像头(索引:0)但面向前方(面对索引:1)。因此使用像 Camera.open(CameraInfo.CAMERA_FACING_FRONT) 这样的简单代码是没有意义的。
    • 这是秃头。甚至不要尝试使用它。
    • 这太可怕了。永远不要这样做。这个答案应该被禁止。 Camera.open() 接受一个摄像头 ID,而不是摄像头朝向的序数值!这在极少数设备上都失败了,而且只能靠运气。
    【解决方案6】:

    Google 已弃用所有旧答案的方法(可能是因为这样的麻烦),因为 API 21 你需要 use Camera 2 API:

    此类已在 API 级别 21 中弃用。我们建议使用新的 android.hardware.camera2 API 用于新应用程序。

    the newer API 中,您对 Android 设备的摄像头和文档拥有几乎完全的权力,并明确建议

    String[] getCameraIdList()
    

    然后使用获取的CameraId打开相机:

    void openCamera(String cameraId, CameraDevice.StateCallback callback, Handler handler)
    

    99%的前置摄像头id = "1",后置摄像头id = "0" 根据这个:

    不可移动的相机使用从 0 开始的整数作为它们的 标识符,而可移动相机对每个都有一个唯一的标识符 单个设备,即使它们是同一型号。

    然而,这意味着如果设备情况很少见,例如只有 1 个前置摄像头的平板电脑,您需要计算您拥有多少个嵌入式摄像头,然后下订单相机的重要性(“0”)。所以 CAMERA_FACING_FRONT == 1 CAMERA_FACING_BACK == 0,这意味着后置摄像头比前置摄像头更重要

    我不知道在所有 Android 设备上识别前置摄像头的统一方法。简单地说,由于某些原因,设备内部的 Android 操作系统无法真正找出哪个摄像头的确切位置:也许唯一的摄像头硬编码 id 是一个表示其重要性的整数,或者在某些设备上,无论您转向哪一边都会是..”回来”。

    文档https://developer.android.com/reference/android/hardware/camera2/package-summary.html

    显式示例https://github.com/googlesamples/android-Camera2Basic


    对于较旧的 API(不建议这样做,因为它不适用于较新的 Android 版本的现代手机,并且传输很麻烦)。只需使用相同的 Integer CameraID (1) 打开前置摄像头,就像在this answer 中一样:

    cam = Camera.open(1);
    

    如果您信任 OpenCV 来做相机部分:

    里面

        <org.opencv.android.JavaCameraView
        ../>
    

    使用以下前置摄像头:

            opencv:camera_id="1"
    

    【讨论】:

      【解决方案7】:

      对于 API 21 (5.0) 及更高版本,您可以使用 CameraManager API's

      try {
          String desiredCameraId = null;
          for(String cameraId : mCameraIDsList) {
              CameraCharacteristics chars =  mCameraManager.getCameraCharacteristics(cameraId);
              List<CameraCharacteristics.Key<?>> keys = chars.getKeys();
              try {
                  if(CameraCharacteristics.LENS_FACING_FRONT == chars.get(CameraCharacteristics.LENS_FACING)) {
                     // This is the one we want.
                     desiredCameraId = cameraId;
                     break;
                  }
              } catch(IllegalArgumentException e) {
                  // This key not implemented, which is a bit of a pain. Either guess - assume the first one
                  // is rear, second one is front, or give up.
              }
          }
      }
      

      【讨论】:

        【解决方案8】:

        build.gradle

         dependencies {
               compile 'com.google.android.gms:play-services-vision:9.4.0+'
            }
        

        设置视图

        CameraSourcePreview mPreview = (CameraSourcePreview) findViewById(R.id.preview);
        
        GraphicOverlay mGraphicOverlay = (GraphicOverlay) findViewById(R.id.faceOverlay);
        
        CameraSource mCameraSource = new CameraSource.Builder(context, detector)
                                    .setRequestedPreviewSize(640, 480)
                                    .setFacing(CameraSource.CAMERA_FACING_FRONT)
                                    .setRequestedFps(30.0f)
                                    .build();
        
                   mPreview.start(mCameraSource, mGraphicOverlay);
        

        【讨论】:

          【解决方案9】:

          打开后置摄像头:-

          val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
          startActivityForResult(cameraIntent, REQUEST_CODE_CAMERA)
          

          打开前置摄像头:-

          val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
          when {
               Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1 && Build.VERSION.SDK_INT < Build.VERSION_CODES.O -> {
                   cameraIntent.putExtra("android.intent.extras.CAMERA_FACING", CameraCharacteristics.LENS_FACING_FRONT)  // Tested on API 24 Android version 7.0(Samsung S6)
               }
               Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> {
                   cameraIntent.putExtra("android.intent.extras.CAMERA_FACING", CameraCharacteristics.LENS_FACING_FRONT) // Tested on API 27 Android version 8.0(Nexus 6P)
                   cameraIntent.putExtra("android.intent.extra.USE_FRONT_CAMERA", true)
               }
               else -> cameraIntent.putExtra("android.intent.extras.CAMERA_FACING", 1)  // Tested API 21 Android version 5.0.1(Samsung S4)
          }
          startActivityForResult(cameraIntent, REQUEST_CODE_CAMERA)
          

          我无法使其适用于 API 28 及更高版本。此外,某些设备无法直接打开前置摄像头(取决于制造商)。

          【讨论】:

          • 对于 API 28 及更高版本,您有解决方案吗?
          【解决方案10】:

          我发现这很好用。

          fun frontCamera(context: Context): Int {
              val cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
              return cameraManager.cameraIdList
                  .find { id ->
                      cameraManager.getCameraCharacteristics(id)[LENS_FACING] == LENS_FACING_FRONT
                  }?.toInt() ?: 0
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-06-06
            • 1970-01-01
            • 1970-01-01
            • 2011-08-31
            • 1970-01-01
            相关资源
            最近更新 更多