Kamerayı kontrol etme

Bu derste ise kamera donanımını doğrudan çerçeve API'leri.

Not: Bu sayfa, kullanımdan kaldırılan Kamera sınıfıyla ilgilidir. KameraX veya belirli kullanım alanları için Kamera2 kullanılmasını öneririz. Hem CameraX hem de Camera2, Android 5.0 (API düzeyi 21) ve sonraki sürümleri destekler.

Bir cihaz kamerasını doğrudan kontrol etmek, resim veya video isteğinde bulunmaya kıyasla çok daha fazla kod gerektirir mevcut kamera uygulamalarından seçebilirsiniz. Ancak özel bir kamera uygulaması geliştirmek veya uygulamanızın kullanıcı arayüzüne tamamen entegre bir şey eklemek istiyorsanız, bu derste size

Aşağıdaki ilgili kaynaklara bakın:

Kamera Nesnesi'ni aç

Camera nesnesinin bir örneğini almak, göz atabilirsiniz. Android'in kendi Kamera uygulamasının yaptığı gibi, kameraya erişmek için önerilen yol, Camera öğesini ayrı bir ileti dizisinde açmaktır bu program onCreate() itibarıyla başladı. Bu yaklaşım, çünkü bu biraz zaman alabilir ve kullanıcı arayüzü iş parçacıklarını tıkayabilir. Daha temel bir uygulamada kod yeniden kullanımını kolaylaştırmak ve içeriğin akışını korumak için kameranın açılması onResume() kontrol etmek çok kolay.

Camera.open() çağrıldığında kamera başka bir uygulama tarafından kullanılıyorsa özel bir istisna oluşturur; bu yüzden kamerayı try blokta.

Kotlin

private fun safeCameraOpen(id: Int): Boolean {
    return try {
        releaseCameraAndPreview()
        mCamera = Camera.open(id)
        true
    } catch (e: Exception) {
        Log.e(getString(R.string.app_name), "failed to open Camera")
        e.printStackTrace()
        false
    }
}

private fun releaseCameraAndPreview() {
    preview?.setCamera(null)
    mCamera?.also { camera ->
        camera.release()
        mCamera = null
    }
}

Java

private boolean safeCameraOpen(int id) {
    boolean qOpened = false;

    try {
        releaseCameraAndPreview();
        camera = Camera.open(id);
        qOpened = (camera != null);
    } catch (Exception e) {
        Log.e(getString(R.string.app_name), "failed to open Camera");
        e.printStackTrace();
    }

    return qOpened;
}

private void releaseCameraAndPreview() {
    preview.setCamera(null);
    if (camera != null) {
        camera.release();
        camera = null;
    }
}

API düzeyi 9'dan itibaren kamera çerçevesi birden fazla kamerayı destekler. URL'yi olmadan open() çağırın ve eski API'yi ilk arka kamerayı alırsınız.

Kamera Önizlemesini Oluşturma

Resim çekmek için genellikle kullanıcılarınızın tıklamadan önce konularının bir önizlemesini görmeleri gerekir deklanşöre dokunun. Bunu yapmak için, bir SurfaceView kullanarak kamera sensörü çalışıyor.

Sınıfı Önizle

Önizleme göstermeye başlamak için önizleme sınıfına ihtiyacınız vardır. İlgili içeriği oluşturmak için kullanılan önizleme, görüntüyü aktarmak için kullanılan android.view.SurfaceHolder.Callback arayüzünün uygulanmasını gerektirir verileri kamera donanımından uygulamaya geçiriyor.

Kotlin

class Preview(
        context: Context,
        val surfaceView: SurfaceView = SurfaceView(context)
) : ViewGroup(context), SurfaceHolder.Callback {

    var mHolder: SurfaceHolder = surfaceView.holder.apply {
        addCallback(this@Preview)
        setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS)
    }
    ...
}

Java

class Preview extends ViewGroup implements SurfaceHolder.Callback {

    SurfaceView surfaceView;
    SurfaceHolder holder;

    Preview(Context context) {
        super(context);

        surfaceView = new SurfaceView(context);
        addView(surfaceView);

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        holder = surfaceView.getHolder();
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }
...
}

Önizleme sınıfı, canlı yayından önce Camera nesnesine iletilmelidir resim önizlemesi, sonraki bölümde gösterildiği gibi başlatılabilir.

Önizlemeyi Ayarlama ve Başlatma

Kamera örneği ve ilgili önizlemesi, belirli bir konumda oluşturulmalıdır. ilk sırada kamera nesnesi olacak. Aşağıdaki snippet'te kamerayı başlatma süreci kapsüllenir, böylece Camera.startPreview() setCamera() yöntemini kullanan içerik üreticiler, bulun. Önizlemenin, önizleme sınıfı surfaceChanged() geri çağırma yönteminde de yeniden başlatılması gerekir.

Kotlin

fun setCamera(camera: Camera?) {
    if (mCamera == camera) {
        return
    }

    stopPreviewAndFreeCamera()

    mCamera = camera

    mCamera?.apply {
        mSupportedPreviewSizes = parameters.supportedPreviewSizes
        requestLayout()

        try {
            setPreviewDisplay(holder)
        } catch (e: IOException) {
            e.printStackTrace()
        }

        // Important: Call startPreview() to start updating the preview
        // surface. Preview must be started before you can take a picture.
        startPreview()
    }
}

Java

public void setCamera(Camera camera) {
    if (mCamera == camera) { return; }

    stopPreviewAndFreeCamera();

    mCamera = camera;

    if (mCamera != null) {
        List<Size> localSizes = mCamera.getParameters().getSupportedPreviewSizes();
        supportedPreviewSizes = localSizes;
        requestLayout();

        try {
            mCamera.setPreviewDisplay(holder);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // Important: Call startPreview() to start updating the preview
        // surface. Preview must be started before you can take a picture.
        mCamera.startPreview();
    }
}

Kamera Ayarlarını Değiştir

Kamera ayarları, kameranın resim çekme biçimini, yakınlaştırma veya uzaklaştırmadan bir artış olacaktır. Bu örnek yalnızca önizleme boyutunu değiştirir; daha pek çok bilgi için Kamera uygulamasının kaynak koduna bakın.

Kotlin

override fun surfaceChanged(holder: SurfaceHolder, format: Int, w: Int, h: Int) {
    mCamera?.apply {
        // Now that the size is known, set up the camera parameters and begin
        // the preview.
        parameters?.also { params ->
            params.setPreviewSize(previewSize.width, previewSize.height)
            requestLayout()
            parameters = params
        }

        // Important: Call startPreview() to start updating the preview surface.
        // Preview must be started before you can take a picture.
        startPreview()
    }
}

Java

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    // Now that the size is known, set up the camera parameters and begin
    // the preview.
    Camera.Parameters parameters = mCamera.getParameters();
    parameters.setPreviewSize(previewSize.width, previewSize.height);
    requestLayout();
    mCamera.setParameters(parameters);

    // Important: Call startPreview() to start updating the preview surface.
    // Preview must be started before you can take a picture.
    mCamera.startPreview();
}

Önizleme Yönünü Ayarla

Çoğu kamera uygulaması, ekranı yatay modda kilitlediği için kamera sensörünün yönü. Bu ayar, dikey modda fotoğraf çekmenizi engellemez çünkü cihazın yönü EXIF başlığına kaydedilir. setCameraDisplayOrientation() yöntemiyle değişiklik yapabilirsiniz. önizlemenin, resmin kaydedilme şeklini etkilemeden nasıl görüntüleneceğini belirler. Ancak önceki Android sürümünde API düzeyi 14'e geri dönmek için yönü değiştirmeden önce önizlemenizi durdurmanız ve ardından yeniden başlatmanız gerekir.

Resim Çekin

Camera.takePicture() kullanın resim çekme yöntemini kullanabilirsiniz. Camera.PictureCallback ve Camera.ShutterCallback nesneleri oluşturup Camera.takePicture() içinde aktarabilirsiniz.

Görüntüleri sürekli olarak yakalamak istiyorsanız onPreviewFrame() uygulayan bir Camera.PreviewCallback oluşturabilirsiniz. Örneğin, yalnızca seçili önizleme karelerini yakalayabilir veya takePicture() araması için geciken işlem.

Önizlemeyi yeniden başlatma

Resim çekildikten sonra, kullanıcı bir resim çekildikten sonra önizlemeyi başka bir fotoğraf çekebilir. Bu örnekte, yeniden başlatma işlemi aşırı yükleme deklanşör düğmesine basın.

Kotlin

fun onClick(v: View) {
    previewState = if (previewState == K_STATE_FROZEN) {
        camera?.startPreview()
        K_STATE_PREVIEW
    } else {
        camera?.takePicture(null, rawCallback, null)
        K_STATE_BUSY
    }
    shutterBtnConfig()
}

Java

@Override
public void onClick(View v) {
    switch(previewState) {
    case K_STATE_FROZEN:
        camera.startPreview();
        previewState = K_STATE_PREVIEW;
        break;

    default:
        camera.takePicture( null, rawCallback, null);
        previewState = K_STATE_BUSY;
    } // switch
    shutterBtnConfig();
}

Önizlemeyi Durdurun ve Kamerayı Bırakın

Uygulamanız kamerayı kullanarak tamamladıktan sonra sıradaki şey temizlik yapmaktır. İçinde Camera nesnesini serbest bırakmanız gerekir. Aksi takdirde diğer kendi uygulamanızın yeni örnekleri de dahil olmak üzere

Önizlemeyi ne zaman durdurup kamerayı serbest bırakmalısınız? Öncelikle kişisel önizleme yüzeyinin tahrip edilmiş olması, bu işlemi durdurmanın zamanının geldiği Preview sınıfındaki bu yöntemlerde gösterildiği gibi kamerayı önizleyip bırakın.

Kotlin

override fun surfaceDestroyed(holder: SurfaceHolder) {
    // Surface will be destroyed when we return, so stop the preview.
    // Call stopPreview() to stop updating the preview surface.
    mCamera?.stopPreview()
}

/**
 * When this function returns, mCamera will be null.
 */
private fun stopPreviewAndFreeCamera() {
    mCamera?.apply {
        // Call stopPreview() to stop updating the preview surface.
        stopPreview()

        // Important: Call release() to release the camera for use by other
        // applications. Applications should release the camera immediately
        // during onPause() and re-open() it during onResume()).
        release()

        mCamera = null
    }
}

Java

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    // Surface will be destroyed when we return, so stop the preview.
    if (mCamera != null) {
        // Call stopPreview() to stop updating the preview surface.
        mCamera.stopPreview();
    }
}

/**
 * When this function returns, mCamera will be null.
 */
private void stopPreviewAndFreeCamera() {

    if (mCamera != null) {
        // Call stopPreview() to stop updating the preview surface.
        mCamera.stopPreview();

        // Important: Call release() to release the camera for use by other
        // applications. Applications should release the camera immediately
        // during onPause() and re-open() it during onResume()).
        mCamera.release();

        mCamera = null;
    }
}

Dersin başlarında bu prosedür aynı zamanda setCamera() yönteminin bir parçasıydı. Dolayısıyla bir kameranın başlatılması her zaman önizle.