Làm cách nào để mở “camera trước” trên nền tảng Android?


82

Nói chung hơn, nếu một thiết bị có nhiều camera được nhúng, có cách nào để khởi tạo một trong số chúng nói riêng không?

Tôi không tìm thấy nó trong tài liệu tham khảo Android:

Samsung SHW-M100S có hai camera. Nếu không có tài liệu tham khảo về việc sử dụng hai camera, bất kỳ ý tưởng nào về việc Samsung đã làm như thế nào ...?


Câu trả lời:


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

Thêm các quyền sau vào AndroidManifest.xmltệp:

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

Lưu ý: Tính năng này có sẵn trong Gingerbread (2.3) và Phiên bản Android Up.


Có thể sử dụng điều này bằng cách nào đó với Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);kỹ thuật mở ứng dụng máy ảnh hiện có không?
loeschg

3
@loeschg Intentxử lý hành động của camera theo cách riêng của nó. Kỹ thuật này được sử dụng khi bạn đang sử dụng SurfaceViewđể khai thác chức năng của máy ảnh.

đó là những gì tôi đã hình dung. Cảm ơn!
loeschg

2
Bài rất hay. Tôi mất một lúc để tìm ra rằng hướng camera không nhất thiết giống với chỉ số camera. Ví dụ: máy tính bảng của tôi chỉ có một camera (chỉ số: 0) nhưng quay mặt trước (chỉ số hướng: 1). Vì vậy, sử dụng mã đơn giản như Camera.open (CameraInfo.CAMERA_FACING_FRONT) là vô nghĩa.
Matthias

@Matthias Đồng ý với bạn đời. Khi chúng tôi có các OEM khác nhau, kỹ thuật lập trình của chúng tôi được thay đổi theo nhu cầu của chúng tôi. Cảm ơn vì đã làm nổi bật.

14

Tất cả các phương pháp của câu trả lời cũ hơn không được Google chấp nhận (được cho là vì những rắc rối như thế này), vì API 21, bạn cần sử dụng API Máy ảnh 2:

Lớp này không được chấp nhận ở cấp độ API 21. Chúng tôi khuyên bạn nên sử dụng API android.hardware.camera2 mới cho các ứng dụng mới.

Trong API mới hơn, bạn gần nhưtoàn quyền đối với camera của thiết bị Android và tài liệu hướng dẫn rõ ràng

String[] getCameraIdList()

và sau đó sử dụng CameraId thu được để mở camera:

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

99% camera trước có id = "1" và camera sau id = "0" theo điều này:

Máy ảnh không thể tháo rời sử dụng các số nguyên bắt đầu từ 0 cho số nhận dạng của chúng, trong khi máy ảnh rời có số nhận dạng duy nhất cho từng thiết bị riêng lẻ, ngay cả khi chúng là cùng một kiểu máy.

Tuy nhiên , điều này có nghĩa là nếu tình huống thiết bị hiếm gặp như máy tính bảng màn hình 1 mặt trước, bạn cần đếm số lượng camera được nhúng và đặt thứ tự của camera theo mức độ quan trọng của nó ("0"). Vì vậy CAMERA_FACING_FRONT == 1 CAMERA_FACING_BACK == 0, có nghĩa là camera sau quan trọng hơn camera trước.

Tôi không biết về một phương pháp thống nhất để xác định camera trước trên tất cả các thiết bị Android. Nói một cách đơn giản, hệ điều hành Android bên trong thiết bị thực sự không thể tìm ra máy ảnh nào chính xác ở đâu vì một số lý do: có thể id mã hóa cứng máy ảnh duy nhất là một số nguyên đại diện cho tầm quan trọng của nó hoặc có thể trên một số thiết bị mà bạn quay về phía nào .. " trở lại".

Tài liệu : https://developer.android.com/reference/android/hardware/camera2/package-summary.html

Ví dụ rõ ràng : https://github.com/googlesamples/android-Camera2Basic


Đối với API cũ hơn (nó không được khuyến khích, vì nó sẽ không hoạt động trên điện thoại hiện đại phiên bản Android mới hơn và việc chuyển giao là một điều khó khăn). Chỉ cần sử dụng cùng một Integer CameraID (1) để mở camera phía trước như trong câu trả lời sau:

cam = Camera.open(1);

Nếu bạn tin tưởng OpenCV thực hiện phần camera:

Phía trong

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

sử dụng các tính năng sau cho camera trước:

        opencv:camera_id="1"

10

Kể từ Android 2.1, Android chỉ hỗ trợ một camera duy nhất trong SDK của nó. Có khả năng điều này sẽ được thêm vào trong một bản phát hành Android trong tương lai.


1
trạng thái này có hợp lệ cho Android 2.2 không?
ozmank

2
@ozmank: Có, hỗ trợ nhiều camera không được bổ sung cho đến Android 2.3.
CommonsWare

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

3
Hoạt động tốt trên Galaxy S Quan trọng là "camera-id" không phải "camera_id"
Mahesh

3
Đừng bao giờ cho rằng 90 độ sẽ giúp bạn xoay đúng ảnh chân dung. Nó khác nhau trên nhiều thiết bị.
colintheshots

4

Đối với API 21 (5.0) trở lên, bạn có thể sử dụng API CameraManager

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

4

Để mở lại camera: -

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

Để mở camera trước : -

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)

Tôi không thể làm cho nó hoạt động cho API 28 trở lên. Ngoài ra, không thể mở trực tiếp camera trước ở một số thiết bị (tùy thuộc vào nhà sản xuất).


2

Với việc phát hành Android 2.3 (Gingerbread), giờ đây bạn có thể sử dụng android.hardware.Cameralớp để lấy số lượng máy ảnh, thông tin về một máy ảnh cụ thể và nhận tham chiếu đến một máy ảnh cụ thể Camera. Kiểm tra các CameraAPI mới tại đây .


1

build.gradle

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

Đặt chế độ xem

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

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

/ * Đây không phải là cách thích hợp, đây là giải pháp cho các thiết bị cũ chạy Android 4.0 trở lên. Điều này có thể được sử dụng cho mục đích thử nghiệm, nhưng không được khuyến khích cho phát triển chính. Giải pháp này chỉ có thể coi là giải pháp tạm thời. Nhưng giải pháp này đã giúp được nhiều người nên tôi không có ý định xóa câu trả lời này * /


7
Tôi không nghĩ đó là cách sử dụng được ghi chép lại. open (int id) chấp nhận id, không phải vị trí máy ảnh
XY

13
vui lòng xóa câu trả lời gây hiểu lầm này
Alex Cohn

13
@AmalanDhananjayan: xem ví dụ như nhận xét của @Matthias ở trên :
Alex Cohn

5
Đây là balderdash. Đừng cố gắng sử dụng cái này.
Adam

4
Điều này thật kinh khủng. Đừng BAO GIỜ làm điều này. Câu trả lời này nên bị cấm. Camera.open () chấp nhận một id máy ảnh, không phải giá trị thứ tự của mặt máy ảnh! Điều này không thành công trên một số ít thiết bị đáng kể và chỉ hoạt động nhờ may mắn tuyệt đối.
colintheshots
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.