खोज…


पैरामीटर

पैरामीटर विवरण
CameraCaptureSession CameraDevice लिए कॉन्फ़िगर किया गया कैप्चर सेशन, जिसका उपयोग कैमरे से छवियों को कैप्चर करने के लिए किया जाता है या पहले वाले कैमरे में कैमरे से कैप्चर की गई छवियों को पुन: प्रस्तुत करने के लिए किया जाता है।
CameraDevice एक Android डिवाइस से जुड़े एकल कैमरे का प्रतिनिधित्व
CameraCharacteristics CameraDevice का वर्णन करने वाले गुण। ये गुण किसी दिए गए CameraDevice के लिए तय किए गए हैं, और getCameraCharacteristics(String) साथ getCameraCharacteristics(String) इंटरफ़ेस के माध्यम से इसे देखा जा सकता है
CameraManager CameraDevices पता लगाने, चिह्नित करने और कनेक्ट करने के लिए एक सिस्टम सेवा प्रबंधक। आप Context.getSystemService() कॉल करके इस वर्ग का एक उदाहरण प्राप्त कर सकते हैं
CaptureRequest कैमरा डिवाइस से एकल छवि को कैप्चर करने के लिए आवश्यक सेटिंग्स और आउटपुट का एक अपरिवर्तनीय पैकेज। कब्जा हार्डवेयर (सेंसर, लेंस, फ्लैश), प्रसंस्करण पाइपलाइन, नियंत्रण एल्गोरिदम और आउटपुट बफ़र्स के लिए कॉन्फ़िगरेशन शामिल है। इस कैप्चर के लिए छवि डेटा भेजने के लिए लक्ष्य सतहों की सूची भी शामिल है। CaptureRequest.Builder createCaptureRequest(int) कॉल करके प्राप्त किया जा सकता है।
CaptureResult छवि संवेदक से एकल छवि कैप्चर के परिणामों का सबसेट। कैप्चर हार्डवेयर (सेंसर, लेंस, फ्लैश), प्रसंस्करण पाइपलाइन, नियंत्रण एल्गोरिदम और आउटपुट बफ़र्स के लिए अंतिम कॉन्फ़िगरेशन का एक सबसेट शामिल है। यह एक द्वारा निर्मित है CameraDevice एक संसाधित करने के बाद CaptureRequest

टिप्पणियों

  • कैमरा 2 एपीआई एपीआई 21+ (लॉलीपॉप और उससे आगे) में उपलब्ध हैं
  • भले ही एंड्रॉइड डिवाइस में 21+ ROM आधिकारिक तौर पर हो, इस बात की कोई गारंटी नहीं है कि यह Camera2 API को लागू करता है, यह इसे लागू करने के लिए पूरी तरह से निर्माता पर निर्भर है या नहीं (उदाहरण: LG G2 में आधिकारिक लॉलीपॉप समर्थन है, लेकिन कोई Camera2 API नहीं है
  • Camera2 के साथ, कैमरा ("Camera1") को हटा दिया गया है
  • महान शक्ति के साथ महान जिम्मेदारी आती है: इस एपीआई का उपयोग करते समय इसे गड़बड़ाना आसान है।
  • याद रखें, यदि आप केवल अपने ऐप में एक फोटो लेना चाहते हैं, और बस इसे प्राप्त करते हैं, तो आपको कैमरा 2 को लागू करने की आवश्यकता नहीं है, आप डिवाइस के कैमरा ऐप को एक इंटेंट के माध्यम से खोल सकते हैं, और इसे वापस प्राप्त कर सकते हैं।

एक TextureView में मुख्य कैमरा का पूर्वावलोकन करें

इस मामले में, एपीआई 23 के खिलाफ निर्माण, इसलिए अनुमतियों को भी नियंत्रित किया जाता है।

आपको मेनिफेस्ट में निम्नलिखित अनुमति (जहां भी एपीआई स्तर आप उपयोग कर रहे हैं) में जोड़ना होगा:

<uses-permission android:name="android.permission.CAMERA"/>

हम एक गतिविधि (Camera2Activity.java) बनाने जा रहे हैं, जो डिवाइस के कैमरे के पूर्वावलोकन के साथ एक TextureView भरता है।

हम जिस गतिविधि का उपयोग करने जा रहे हैं वह एक विशिष्ट AppCompatActivity है:

public class Camera2Activity extends AppCompatActivity {

विशेषताएँ (आपको इसमें से कुछ को समझने के लिए पूरे उदाहरण को पढ़ने की आवश्यकता हो सकती है)

MAX_PREVIEW_SIZE camera2 एपीआई द्वारा गारंटी 1920x1080 है

private static final int MAX_PREVIEW_WIDTH = 1920;
private static final int MAX_PREVIEW_HEIGHT = 1080;

TextureView.SurfaceTextureListener एक TextureView पर कई जीवनचक्र की घटनाओं को संभालती है। इस मामले में, हम उन घटनाओं को सुन रहे हैं। जब सर्फेसटेक्स्ट तैयार होता है, तो हम कैमरे को इनिशियलाइज़ करते हैं। जब यह आकार बदलता है, तो हम तदनुसार कैमरे से आने वाले पूर्वावलोकन को सेटअप करते हैं

private final TextureView.SurfaceTextureListener mSurfaceTextureListener
        = new TextureView.SurfaceTextureListener() {

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
        openCamera(width, height);
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) {
        configureTransform(width, height);
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
        return true;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture texture) {
    }

};

एक CameraDevice एक भौतिक उपकरण के कैमरे का प्रतिनिधित्व करता है। इस विशेषता में, हम वर्तमान CameraDevice की आईडी को CameraDevice

private String mCameraId;

यह वह दृश्य ( TextureView ) है जिसका उपयोग हम कैमरे के पूर्वावलोकन को "ड्रा" करने के लिए करेंगे

private TextureView mTextureView;

कैमरा पूर्वावलोकन के लिए CameraCaptureSession

private CameraCaptureSession mCaptureSession;

खोला CameraDevice लिए एक संदर्भ

private CameraDevice mCameraDevice;

कैमरा पूर्वावलोकन का Size

private Size mPreviewSize;

CameraDevice.StateCallback को कहा जाता है जब CameraDevice अपनी स्थिति बदलता है

private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {

    @Override
    public void onOpened(@NonNull CameraDevice cameraDevice) {
        // This method is called when the camera is opened.  We start camera preview here.
        mCameraOpenCloseLock.release();
        mCameraDevice = cameraDevice;
        createCameraPreviewSession();
    }

    @Override
    public void onDisconnected(@NonNull CameraDevice cameraDevice) {
        mCameraOpenCloseLock.release();
        cameraDevice.close();
        mCameraDevice = null;
    }

    @Override
    public void onError(@NonNull CameraDevice cameraDevice, int error) {
        mCameraOpenCloseLock.release();
        cameraDevice.close();
        mCameraDevice = null;
        finish();
    }

};

चल रहे कार्यों के लिए एक अतिरिक्त धागा जो UI को ब्लॉक नहीं करना चाहिए

private HandlerThread mBackgroundThread;

पृष्ठभूमि में कार्य चलाने के लिए एक Handler

private Handler mBackgroundHandler;

एक ImageReader जो अभी भी इमेज कैप्चर को हैंडल करता है

private ImageReader mImageReader;

कैमरे के पूर्वावलोकन के लिए CaptureRequest.Builder

private CaptureRequest.Builder mPreviewRequestBuilder;

CaptureRequest द्वारा उत्पन्न mPreviewRequestBuilder

private CaptureRequest mPreviewRequest;

कैमरा बंद करने से पहले ऐप को बाहर निकलने से रोकने के लिए एक Semaphore

private Semaphore mCameraOpenCloseLock = new Semaphore(1);

अनुमति अनुरोध की लगातार आईडी

private static final int REQUEST_CAMERA_PERMISSION = 1;

Android जीवनचक्र विधियाँ

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

    mTextureView = (TextureView) findViewById(R.id.texture);
}

@Override
public void onResume() {
    super.onResume();
    startBackgroundThread();

    // When the screen is turned off and turned back on, the SurfaceTexture is already
    // available, and "onSurfaceTextureAvailable" will not be called. In that case, we can open
    // a camera and start preview from here (otherwise, we wait until the surface is ready in
    // the SurfaceTextureListener).
    if (mTextureView.isAvailable()) {
        openCamera(mTextureView.getWidth(), mTextureView.getHeight());
    } else {
        mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
    }
}

@Override
public void onPause() {
    closeCamera();
    stopBackgroundThread();
    super.onPause();
}

कैमरा 2 संबंधित तरीके

वे तरीके हैं जो कैमरा 2 एपीआई का उपयोग करते हैं

private void openCamera(int width, int height) {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
            != PackageManager.PERMISSION_GRANTED) {
        requestCameraPermission();
        return;
    }
    setUpCameraOutputs(width, height);
    configureTransform(width, height);
    CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
    try {
        if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
            throw new RuntimeException("Time out waiting to lock camera opening.");
        }
        manager.openCamera(mCameraId, mStateCallback, mBackgroundHandler);
    } catch (CameraAccessException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        throw new RuntimeException("Interrupted while trying to lock camera opening.", e);
    }
}

वर्तमान कैमरा बंद करता है

private void closeCamera() {
    try {
        mCameraOpenCloseLock.acquire();
        if (null != mCaptureSession) {
            mCaptureSession.close();
            mCaptureSession = null;
        }
        if (null != mCameraDevice) {
            mCameraDevice.close();
            mCameraDevice = null;
        }
        if (null != mImageReader) {
            mImageReader.close();
            mImageReader = null;
        }
    } catch (InterruptedException e) {
        throw new RuntimeException("Interrupted while trying to lock camera closing.", e);
    } finally {
        mCameraOpenCloseLock.release();
    }
}

कैमरे से संबंधित सदस्य चर सेट करता है

private void setUpCameraOutputs(int width, int height) {
    CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
    try {
        for (String cameraId : manager.getCameraIdList()) {
            CameraCharacteristics characteristics
                    = manager.getCameraCharacteristics(cameraId);

            // We don't use a front facing camera in this sample.
            Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
            if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {
                continue;
            }

            StreamConfigurationMap map = characteristics.get(
                    CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
            if (map == null) {
                continue;
            }

            // For still image captures, we use the largest available size.
            Size largest = Collections.max(
                    Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)),
                    new CompareSizesByArea());
            mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(),
                    ImageFormat.JPEG, /*maxImages*/2);
            mImageReader.setOnImageAvailableListener(
                    null, mBackgroundHandler);

            Point displaySize = new Point();
            getWindowManager().getDefaultDisplay().getSize(displaySize);
            int rotatedPreviewWidth = width;
            int rotatedPreviewHeight = height;
            int maxPreviewWidth = displaySize.x;
            int maxPreviewHeight = displaySize.y;

            if (maxPreviewWidth > MAX_PREVIEW_WIDTH) {
                maxPreviewWidth = MAX_PREVIEW_WIDTH;
            }

            if (maxPreviewHeight > MAX_PREVIEW_HEIGHT) {
                maxPreviewHeight = MAX_PREVIEW_HEIGHT;
            }

            // Danger! Attempting to use too large a preview size could  exceed the camera
            // bus' bandwidth limitation, resulting in gorgeous previews but the storage of
            // garbage capture data.
            mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),
                    rotatedPreviewWidth, rotatedPreviewHeight, maxPreviewWidth,
                    maxPreviewHeight, largest);

            mCameraId = cameraId;
            return;
        }
    } catch (CameraAccessException e) {
        e.printStackTrace();
    } catch (NullPointerException e) {
        // Currently an NPE is thrown when the Camera2API is used but not supported on the
        // device this code runs.
        Toast.makeText(Camera2Activity.this, "Camera2 API not supported on this device", Toast.LENGTH_LONG).show();
    }
}

कैमरा पूर्वावलोकन के लिए एक नया CameraCaptureSession बनाता है

private void createCameraPreviewSession() {
    try {
        SurfaceTexture texture = mTextureView.getSurfaceTexture();
        assert texture != null;

        // We configure the size of default buffer to be the size of camera preview we want.
        texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());

        // This is the output Surface we need to start preview.
        Surface surface = new Surface(texture);

        // We set up a CaptureRequest.Builder with the output Surface.
        mPreviewRequestBuilder
                = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
        mPreviewRequestBuilder.addTarget(surface);

        // Here, we create a CameraCaptureSession for camera preview.
        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);

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

                    @Override
                    public void onConfigureFailed(
                            @NonNull CameraCaptureSession cameraCaptureSession) {
                        showToast("Failed");
                    }
                }, null
        );
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

Android API 23+ के लिए अनुमतियाँ संबंधित तरीके

private void requestCameraPermission() {
    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
        new AlertDialog.Builder(Camera2Activity.this)
                .setMessage("R string request permission")
                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        ActivityCompat.requestPermissions(Camera2Activity.this,
                                new String[]{Manifest.permission.CAMERA},
                                REQUEST_CAMERA_PERMISSION);
                    }
                })
                .setNegativeButton(android.R.string.cancel,
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                finish();

                            }
                        })
                .create();

    } else {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
                REQUEST_CAMERA_PERMISSION);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    if (requestCode == REQUEST_CAMERA_PERMISSION) {
        if (grantResults.length != 1 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(Camera2Activity.this, "ERROR: Camera permissions not granted", Toast.LENGTH_LONG).show();
        }
    } else {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

बैकग्राउंड थ्रेड / हैंडलर तरीके

private void startBackgroundThread() {
    mBackgroundThread = new HandlerThread("CameraBackground");
    mBackgroundThread.start();
    mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
}

private void stopBackgroundThread() {
    mBackgroundThread.quitSafely();
    try {
        mBackgroundThread.join();
        mBackgroundThread = null;
        mBackgroundHandler = null;
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

उपयोगिता के तरीके

एक कैमरे द्वारा समर्थित Size विकल्पों को देखते हुए, सबसे छोटा चुनें जो कि संबंधित बनावट के आकार के आकार के अनुसार कम से कम हो, और जो कि संबंधित अधिकतम आकार जितना बड़ा हो, और जिसका पहलू अनुपात निर्दिष्ट मान के साथ मेल खाता हो। यदि मौजूद नहीं है, तो सबसे बड़ा चुनें जो कि संबंधित अधिकतम आकार जितना बड़ा हो, और जिसका पहलू अनुपात निर्दिष्ट मान के साथ मेल खाता हो

private static Size chooseOptimalSize(Size[] choices, int textureViewWidth,
                                      int textureViewHeight, int maxWidth, int maxHeight, Size aspectRatio) {

    // Collect the supported resolutions that are at least as big as the preview Surface
    List<Size> bigEnough = new ArrayList<>();
    // Collect the supported resolutions that are smaller than the preview Surface
    List<Size> notBigEnough = new ArrayList<>();
    int w = aspectRatio.getWidth();
    int h = aspectRatio.getHeight();
    for (Size option : choices) {
        if (option.getWidth() <= maxWidth && option.getHeight() <= maxHeight &&
                option.getHeight() == option.getWidth() * h / w) {
            if (option.getWidth() >= textureViewWidth &&
                    option.getHeight() >= textureViewHeight) {
                bigEnough.add(option);
            } else {
                notBigEnough.add(option);
            }
        }
    }

    // Pick the smallest of those big enough. If there is no one big enough, pick the
    // largest of those not big enough.
    if (bigEnough.size() > 0) {
        return Collections.min(bigEnough, new CompareSizesByArea());
    } else if (notBigEnough.size() > 0) {
        return Collections.max(notBigEnough, new CompareSizesByArea());
    } else {
        Log.e("Camera2", "Couldn't find any suitable preview size");
        return choices[0];
    }
}

यह विधि mTextureView को neccesary Matrix परिवर्तन की mTextureView

private void configureTransform(int viewWidth, int viewHeight) {
    if (null == mTextureView || null == mPreviewSize) {
        return;
    }
    int rotation = getWindowManager().getDefaultDisplay().getRotation();
    Matrix matrix = new Matrix();
    RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
    RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth());
    float centerX = viewRect.centerX();
    float centerY = viewRect.centerY();
    if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
        bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
        matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
        float scale = Math.max(
                (float) viewHeight / mPreviewSize.getHeight(),
                (float) viewWidth / mPreviewSize.getWidth());
        matrix.postScale(scale, scale, centerX, centerY);
        matrix.postRotate(90 * (rotation - 2), centerX, centerY);
    } else if (Surface.ROTATION_180 == rotation) {
        matrix.postRotate(180, centerX, centerY);
    }
    mTextureView.setTransform(matrix);
}

यह विधि उनके क्षेत्रों के आधार पर दो Size तुलना करती है।

static class CompareSizesByArea implements Comparator<Size> {

    @Override
    public int compare(Size lhs, Size rhs) {
        // We cast here to ensure the multiplications won't overflow
        return Long.signum((long) lhs.getWidth() * lhs.getHeight() -
                (long) rhs.getWidth() * rhs.getHeight());
    }
}

यहां देखने के लिए ज्यादा नहीं है

/**
 * Shows a {@link Toast} on the UI thread.
 *
 * @param text The message to show
 */
private void showToast(final String text) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            Toast.makeText(Camera2Activity.this, text, Toast.LENGTH_SHORT).show();
        }
    });
}


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow