Kamera API'si

Android çerçevesi, cihazlarda kullanılabilen çeşitli kamera ve kamera özellikleri için destek sunarak uygulamalarınızda resim ve video çekmenize olanak tanır. Bu dokümanda, hızlı ve basit bir resim ve video çekimi yaklaşımının yanı sıra kullanıcılarınız için özel kamera deneyimleri oluşturmaya yönelik gelişmiş bir yaklaşım özetlenmektedir.

Not: Bu sayfada, kullanımdan kaldırılan Camera sınıfı açıklanmaktadır. KameraX Jetpack kitaplığını veya belirli kullanım alanları için camera2 sınıfını kullanmanızı öneririz. CameraX ve Camera2, Android 5.0 (API düzeyi 21) ve sonraki sürümlerde çalışır.

Aşağıdaki ilgili kaynakları inceleyin:

Dikkat edilmesi gereken noktalar

Uygulamanızın Android cihazlardaki kameraları kullanmasını sağlamadan önce, uygulamanızın bu donanım özelliğini nasıl kullanmayı amaçladığıyla ilgili birkaç soruyu değerlendirmeniz gerekir.

  • Kamera Gereksinimi - Uygulamanız için kamera kullanımı o kadar önemli mi ki, uygulamanızın kamerası olmayan bir cihaza yüklenmesini istemiyor musunuz? Bu durumda kamera gereksinimini manifest'inizde beyan etmeniz gerekir.
  • Hızlı Resim veya Özelleştirilmiş Kamera: Uygulamanız kamerayı nasıl kullanacak? Sadece hızlı bir resim veya video klip mi çekmek istiyorsunuz yoksa uygulamanız, kameraları kullanmak için yeni bir yol mu sağlayacak? Hızlı bir fotoğraf çekmek veya klip çekmek için Mevcut Kamera Uygulamalarını Kullanma bölümüne göz atın. Özelleştirilmiş bir kamera özelliği geliştirmek için Kamera Uygulaması Oluşturma bölümüne bakın.
  • Ön Plan Hizmeti Şartı: Uygulamanız kamerayla ne zaman etkileşime geçiyor? Android 9 (API düzeyi 28) ve sonraki sürümlerde arka planda çalışan uygulamalar kameraya erişemez. Bu nedenle, kamerayı uygulamanız ön plandayken veya bir ön plan hizmetinin parçası olarak kullanırken kullanmalısınız.
  • Depolama: Uygulamanızın oluşturduğu resimler veya videolar yalnızca uygulamanız tarafından görülebilecek şekilde mi yoksa Galeri ya da diğer medya uygulamaları ve sosyal uygulamalar gibi diğer uygulamaların da kullanabileceği şekilde mi paylaşılıyor? Uygulamanız kaldırılmış olsa bile resimlerin ve videoların kullanılabilir olmasını istiyor musunuz? Bu seçeneklerin nasıl uygulanacağını görmek için Medya Dosyalarını Kaydetme bölümüne bakın.

Temel bilgiler

Android çerçevesi, android.hardware.camera2 API veya kamera Intent ile görüntü ve video yakalamayı destekler. İlgili sınıflar şunlardır:

android.hardware.camera2
Bu paket, cihaz kameralarını kontrol etmek için kullanılan birincil API'dir. Bir kamera uygulaması oluştururken resim veya video çekmek için kullanılabilir.
Camera
Bu sınıf, cihaz kameralarını kontrol etmek için kullanılan ve desteği sonlandırılmış API'dir.
SurfaceView
Bu sınıf, kullanıcıya canlı kamera önizlemesi sunmak için kullanılır.
MediaRecorder
Bu sınıf, kameradan video kaydetmek için kullanılır.
Intent
Amaç işlemi türü MediaStore.ACTION_IMAGE_CAPTURE veya MediaStore.ACTION_VIDEO_CAPTURE, Camera nesnesini doğrudan kullanmadan resim veya video çekmek için kullanılabilir.

Manifest beyanları

Camera API ile uygulamanızı geliştirmeye başlamadan önce, manifest'inizde kamera donanımının ve diğer ilgili özelliklerin kullanımına izin veren uygun beyanların yer aldığından emin olun.

  • Kamera İzni: Uygulamanız, cihaz kamerasını kullanmak için izin istemelidir.
    <uses-permission android:name="android.permission.CAMERA" />
    

    Not: Kamerayı mevcut bir kamera uygulamasını çağırarak kullanıyorsanız uygulamanızın bu izni istemesine gerek yoktur.

  • Kamera Özellikleri: Uygulamanız, kamera özelliklerinin kullanımını da beyan etmelidir. Örneğin:
    <uses-feature android:name="android.hardware.camera" />
    

    Kamera özelliklerinin listesi için manifest Özellikler Referansı'na bakın.

    Manifest dosyanıza kamera özellikleri eklemek, Google Play'in uygulamanızın kamera içermeyen veya belirlediğiniz kamera özelliklerini desteklemeyen cihazlara yüklenmesini engellemesine neden olur. Google Play ile özellik tabanlı filtreleme kullanma hakkında daha fazla bilgi için Google Play ve Özellik Tabanlı Filtreleme bölümüne bakın.

    Uygulamanız düzgün çalışması için bir kamera veya kamera özelliğini kullanabiliyorsa ancak bu özelliği gerektirmiyorsa, manifest dosyasında android:required özelliğini ekleyip false olarak ayarlayarak bunu belirtmeniz gerekir:

    <uses-feature android:name="android.hardware.camera" android:required="false" />
    
  • Depolama İzni: Uygulamanız, Android 10 (API düzeyi 29) veya altını hedefliyorsa ve manifest dosyasında aşağıdakileri belirtiyorsa resimleri veya videoları cihazın harici depolama alanına (SD Kart) kaydedebilir.
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    
  • Ses Kaydı İzni: Video yakalama özelliğiyle ses kaydetmek için uygulamanızın ses yakalama izni istemesi gerekir.
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    
  • Konum İzni: Uygulamanız, resimleri GPS konum bilgileriyle etiketliyorsa ACCESS_FINE_LOCATION iznini istemeniz gerekir. Uygulamanız Android 5.0 (API düzeyi 21) veya sonraki bir sürümü hedefliyorsa uygulamanızın cihazın GPS'ini kullandığını da beyan etmeniz gerekir:

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    ...
    <!-- Needed only if your app targets Android 5.0 (API level 21) or higher. -->
    <uses-feature android:name="android.hardware.location.gps" />
    

    Kullanıcı konumunu alma hakkında daha fazla bilgi için Konum Stratejileri'ne bakın.

Mevcut kamera uygulamalarını kullanma

Uygulamanızda çok fazla koda gerek olmadan resim veya video çekmeyi etkinleştirmenin hızlı bir yolu, mevcut bir Android kamera uygulamasını çağırmak için Intent kullanmaktır. Bu konuyla ilgili ayrıntılar, Basit Fotoğraf Çekme ve Video Kaydetme başlıklı eğitim derslerinde açıklanmıştır.

Kamera uygulaması oluşturma

Bazı geliştiriciler, uygulamalarının görünümüne göre özelleştirilmiş veya özel özellikler sunan bir kamera kullanıcı arayüzüne ihtiyaç duyabilir. Kendi resim alma kodunuzu yazmak, kullanıcılarınıza daha ilgi çekici bir deneyim sunabilir.

Not: Aşağıdaki kılavuz, eski ve kullanımdan kaldırılan Camera API içindir. Yeni veya gelişmiş kamera uygulamaları için daha yeni android.hardware.camera2 API önerilir.

Uygulamanız için özel bir kamera arayüzü oluşturmaya yönelik genel adımlar şunlardır:

  • Kamerayı Algıla ve Kameraya Eriş - Kameraların olup olmadığını kontrol etmek ve erişim isteğinde bulunmak için kod oluşturun.
  • Önizleme Sınıfı Oluşturma - SurfaceView'yi genişleten ve SurfaceHolder arayüzünü uygulayan bir kamera önizleme sınıfı oluşturun. Bu derste, kameradan canlı resimlerin önizlemesi yapılır.
  • Önizleme Düzeni oluşturun - Kamera önizleme sınıfını oluşturduktan sonra, istediğiniz önizleme ve kullanıcı arayüzü denetimlerini içeren bir görünüm düzeni oluşturun.
  • Video Kayıt için İşleyicileri Ayarlayın - Bir düğmeye basmak gibi kullanıcı işlemlerine yanıt olarak görüntü veya video yakalamayı başlatmak için arayüz kontrolleriniz için işleyicileri bağlayın.
  • Dosyaları Çek ve Kaydet - Resim veya video çekmek ve çıkışı kaydetmek için kodu ayarlayın.
  • Kamerayı Bırakın - Kamerayı kullandıktan sonra, uygulamanız diğer uygulamaların kullanılabilmesi için düzgün şekilde serbest bırakmalıdır.

Kamera donanımı, uygulamanızın, onu kullanmak isteyebilecek diğer uygulamalarla çakışmaması için dikkatli bir şekilde yönetilmesi gereken paylaşılan bir kaynaktır. Aşağıdaki bölümlerde kamera donanımının nasıl algılanacağı, kameraya erişim isteğinde nasıl bulunulacağı, resim veya video çekilme ve uygulamanız tamamlandığında kameranın nasıl serbest bırakılacağı anlatılmaktadır.

Dikkat: Uygulamanızın kullanılması bittiğinde Camera.release() öğesini çağırarak Camera nesnesini serbest bırakmayı unutmayın. Uygulamanız, kamerayı doğru bir şekilde serbest bırakmazsa kendi uygulamanızın yaptıkları da dahil olmak üzere kameraya erişmeye yönelik sonraki tüm girişimler başarısız olur ve sizin veya diğer uygulamalarınızın kapatılmasına neden olabilir.

Kamera donanımı algılanıyor

Uygulamanız, manifest beyanı kullanarak özellikle kamera kullanılmasını gerektirmiyorsa çalışma zamanında bir kameranın kullanılabilir olup olmadığını kontrol etmeniz gerekir. Bu kontrolü gerçekleştirmek için aşağıdaki örnek kodda gösterildiği gibi PackageManager.hasSystemFeature() yöntemini kullanın:

Kotlin

/** Check if this device has a camera */
private fun checkCameraHardware(context: Context): Boolean {
    if (context.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
        // this device has a camera
        return true
    } else {
        // no camera on this device
        return false
    }
}

Java

/** Check if this device has a camera */
private boolean checkCameraHardware(Context context) {
    if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
        // this device has a camera
        return true;
    } else {
        // no camera on this device
        return false;
    }
}

Android cihazlarda birden fazla kamera kullanılabilir. Örneğin, fotoğrafçılık için arka yüz kamerası, görüntülü görüşme için de ön kamera. Android 2.3 (API Düzeyi 9) ve sonraki sürümler Camera.getNumberOfCameras() yöntemini kullanarak bir cihazdaki kullanılabilir kamera sayısını kontrol etmenize olanak tanır.

Kameralara erişme

Uygulamanızın çalıştığı cihazda kamera olduğunu belirlediyseniz Camera örneğini alarak kameraya erişim isteğinde bulunmanız gerekir (kameraya erişme amacı kullanmıyorsanız).

Birincil kameraya erişmek için Camera.open() yöntemini kullanın ve aşağıdaki kodda gösterildiği gibi istisnaları yakaladığınızdan emin olun:

Kotlin

/** A safe way to get an instance of the Camera object. */
fun getCameraInstance(): Camera? {
    return try {
        Camera.open() // attempt to get a Camera instance
    } catch (e: Exception) {
        // Camera is not available (in use or does not exist)
        null // returns null if camera is unavailable
    }
}

Java

/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
    Camera c = null;
    try {
        c = Camera.open(); // attempt to get a Camera instance
    }
    catch (Exception e){
        // Camera is not available (in use or does not exist)
    }
    return c; // returns null if camera is unavailable
}

Dikkat: Camera.open() kullanırken istisnaları her zaman kontrol edin. Kamera kullanımdaysa veya mevcut değilse istisnalar kontrol edilmemesi, uygulamanızın sistem tarafından kapatılmasına neden olur.

Android 2.3 (API Düzeyi 9) veya sonraki sürümleri çalıştıran cihazlarda Camera.open(int) kullanarak belirli kameralara erişebilirsiniz. Yukarıdaki örnek kod, birden fazla kamerası olan bir cihazdaki ilk arka kameraya erişir.

Kamera özellikleri kontrol ediliyor

Bir kameraya erişim elde ettikten sonra Camera.getParameters() yöntemini kullanarak kameranın özellikleri hakkında daha fazla bilgi edinebilir ve desteklenen özellikler için döndürülen Camera.Parameters nesnesini kontrol edebilirsiniz. API Düzeyi 9 veya üstünü kullanırken bir kameranın cihazın önünde mi yoksa arkasında mı olduğunu ve resmin yönünü belirlemek için Camera.getCameraInfo() özelliğini kullanın.

Önizleme sınıfı oluşturma

Kullanıcıların etkili bir şekilde resim veya video çekebilmesi için cihaz kamerasının gördüklerini görebilmesi gerekir. Kamera önizleme sınıfı, kameradan gelen canlı resim verilerini görüntüleyebilen bir SurfaceView'dir. Bu sayede kullanıcılar, çerçeve oluşturup bir resim veya videoyu çekebilir.

Aşağıdaki örnek kod, View düzenine eklenebilecek temel bir kamera önizleme sınıfının nasıl oluşturulacağını gösterir. Bu sınıfta, kamera önizleme girişini atamak için gereken ve görünümü oluşturmaya ve yok etmeye yönelik geri çağırma etkinliklerini yakalamak amacıyla SurfaceHolder.Callback uygulanır.

Kotlin

/** A basic Camera preview class */
class CameraPreview(
        context: Context,
        private val mCamera: Camera
) : SurfaceView(context), SurfaceHolder.Callback {

    private val mHolder: SurfaceHolder = holder.apply {
        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        addCallback(this@CameraPreview)
        // deprecated setting, but required on Android versions prior to 3.0
        setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS)
    }

    override fun surfaceCreated(holder: SurfaceHolder) {
        // The Surface has been created, now tell the camera where to draw the preview.
        mCamera.apply {
            try {
                setPreviewDisplay(holder)
                startPreview()
            } catch (e: IOException) {
                Log.d(TAG, "Error setting camera preview: ${e.message}")
            }
        }
    }

    override fun surfaceDestroyed(holder: SurfaceHolder) {
        // empty. Take care of releasing the Camera preview in your activity.
    }

    override fun surfaceChanged(holder: SurfaceHolder, format: Int, w: Int, h: Int) {
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.
        if (mHolder.surface == null) {
            // preview surface does not exist
            return
        }

        // stop preview before making changes
        try {
            mCamera.stopPreview()
        } catch (e: Exception) {
            // ignore: tried to stop a non-existent preview
        }

        // set preview size and make any resize, rotate or
        // reformatting changes here

        // start preview with new settings
        mCamera.apply {
            try {
                setPreviewDisplay(mHolder)
                startPreview()
            } catch (e: Exception) {
                Log.d(TAG, "Error starting camera preview: ${e.message}")
            }
        }
    }
}

Java

/** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder mHolder;
    private Camera mCamera;

    public CameraPreview(Context context, Camera camera) {
        super(context);
        mCamera = camera;

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        // deprecated setting, but required on Android versions prior to 3.0
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, now tell the camera where to draw the preview.
        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d(TAG, "Error setting camera preview: " + e.getMessage());
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // empty. Take care of releasing the Camera preview in your activity.
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.

        if (mHolder.getSurface() == null){
          // preview surface does not exist
          return;
        }

        // stop preview before making changes
        try {
            mCamera.stopPreview();
        } catch (Exception e){
          // ignore: tried to stop a non-existent preview
        }

        // set preview size and make any resize, rotate or
        // reformatting changes here

        // start preview with new settings
        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();

        } catch (Exception e){
            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
        }
    }
}

Kamera önizlemeniz için belirli bir boyut ayarlamak isterseniz bunu, yukarıdaki yorumlarda belirtildiği gibi surfaceChanged() yönteminde ayarlayın. Önizleme boyutunu ayarlarken getSupportedPreviewSizes() değerlerinden değerler kullanmalısınız. setPreviewSize() yönteminde rastgele değerler ayarlamayın.

Not: Android 7.0 (API seviyesi 24) ve sonraki sürümlerde Çoklu Pencere özelliğinin kullanıma sunulmasıyla birlikte, setDisplayOrientation() çağrısından sonra bile önizlemenin en boy oranının etkinliğinizle aynı olduğunu varsayamazsınız. Pencere boyutuna ve en boy oranına bağlı olarak, dikey yönlü bir düzene geniş kamera önizlemesini (veya tam tersi) sinemaskop düzeni kullanarak geniş kamera önizlemesini sığdırmanız gerekebilir.

Önizlemeyi bir düzene yerleştirme

Önceki bölümde gösterilen örnek gibi bir kamera önizleme sınıfı, fotoğraf veya video çekmek için kullanılan diğer kullanıcı arayüzü kontrolleriyle birlikte etkinliğin düzenine yerleştirilmelidir. Bu bölümde, önizleme için nasıl temel bir düzen ve etkinlik oluşturacağınız gösterilmektedir.

Aşağıdaki düzen kodu, kamera önizlemesini görüntülemek için kullanılabilecek çok temel bir görünüm sağlar. Bu örnekte, FrameLayout öğesinin kamera önizleme sınıfı için kapsayıcı olması amaçlanmıştır. Bu düzen türü, canlı kamera önizleme görüntülerinin üzerine ek resim bilgileri veya kontroller yerleştirilebilmesi için kullanılır.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
  <FrameLayout
    android:id="@+id/camera_preview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    />

  <Button
    android:id="@+id/button_capture"
    android:text="Capture"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    />
</LinearLayout>

Çoğu cihazda kamera önizlemesinin varsayılan yönü yataydır. Bu örnek düzen, yatay (yatay) bir düzeni belirtir ve aşağıdaki kod, uygulamanın yatay yönde yönünü sabitler. Kamera önizlemesi oluşturmada kolaylık sağlaması için, aşağıdakini manifest dosyanıza ekleyerek uygulamanızın önizleme etkinlik yönünü yatay olarak değiştirmeniz gerekir.

<activity android:name=".CameraActivity"
          android:label="@string/app_name"

          android:screenOrientation="landscape">
          <!-- configure this activity to use landscape orientation -->

          <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

Not: Kamera önizlemesinin yatay modda olması gerekmez. Android 2.2'den (API Düzeyi 8) başlayarak, önizleme resminin dönüşünü ayarlamak için setDisplayOrientation() yöntemini kullanabilirsiniz. Kullanıcı telefonun yönünü değiştirirken önizleme yönünü değiştirmek için önizleme sınıfınızın surfaceChanged() yönteminde önce Camera.stopPreview() ile önizlemeyi durdurun ve ardından Camera.startPreview() ile önizlemeyi tekrar başlatın.

Kamera görünümünüz etkinliğinde, önizleme sınıfınızı yukarıdaki örnekte gösterilen FrameLayout öğesine ekleyin. Kamera etkinliğiniz, duraklatıldığında veya kapatıldığında kameranın serbest kalmasını da sağlamalıdır. Aşağıdaki örnekte, Önizleme sınıfı oluşturma bölümünde gösterilen önizleme sınıfını eklemek için kamera etkinliğinin nasıl değiştirileceği gösterilmektedir.

Kotlin

class CameraActivity : Activity() {

    private var mCamera: Camera? = null
    private var mPreview: CameraPreview? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Create an instance of Camera
        mCamera = getCameraInstance()

        mPreview = mCamera?.let {
            // Create our Preview view
            CameraPreview(this, it)
        }

        // Set the Preview view as the content of our activity.
        mPreview?.also {
            val preview: FrameLayout = findViewById(R.id.camera_preview)
            preview.addView(it)
        }
    }
}

Java

public class CameraActivity extends Activity {

    private Camera mCamera;
    private CameraPreview mPreview;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Create an instance of Camera
        mCamera = getCameraInstance();

        // Create our Preview view and set it as the content of our activity.
        mPreview = new CameraPreview(this, mCamera);
        FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
        preview.addView(mPreview);
    }
}

Not: Yukarıdaki örnekte yer alan getCameraInstance() yöntemi, Kameralara erişme bölümünde gösterilen örnek yöntemi ifade eder.

Fotoğraf çekiliyor

Önizleme sınıfı ve bu sınıfı görüntülemek istediğiniz görünüm düzenini oluşturduktan sonra uygulamanızla resim yakalamaya başlayabilirsiniz. Uygulama kodunuzda, kullanıcı arayüzü kontrollerinizin, fotoğraf çekerek bir kullanıcı işlemine yanıt vermesi için işleyiciler ayarlamanız gerekir.

Bir resim almak için Camera.takePicture() yöntemini kullanın. Bu yöntem, kameradan veri alan üç parametre alır. Verileri JPEG biçiminde almak amacıyla görüntü verilerini almak ve bir dosyaya yazmak için bir Camera.PictureCallback arayüzü uygulamanız gerekir. Aşağıdaki kod, kameradan alınan bir resmi kaydetmek için Camera.PictureCallback arayüzünün temel uygulamasını göstermektedir.

Kotlin

private val mPicture = Camera.PictureCallback { data, _ ->
    val pictureFile: File = getOutputMediaFile(MEDIA_TYPE_IMAGE) ?: run {
        Log.d(TAG, ("Error creating media file, check storage permissions"))
        return@PictureCallback
    }

    try {
        val fos = FileOutputStream(pictureFile)
        fos.write(data)
        fos.close()
    } catch (e: FileNotFoundException) {
        Log.d(TAG, "File not found: ${e.message}")
    } catch (e: IOException) {
        Log.d(TAG, "Error accessing file: ${e.message}")
    }
}

Java

private PictureCallback mPicture = new PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {

        File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
        if (pictureFile == null){
            Log.d(TAG, "Error creating media file, check storage permissions");
            return;
        }

        try {
            FileOutputStream fos = new FileOutputStream(pictureFile);
            fos.write(data);
            fos.close();
        } catch (FileNotFoundException e) {
            Log.d(TAG, "File not found: " + e.getMessage());
        } catch (IOException e) {
            Log.d(TAG, "Error accessing file: " + e.getMessage());
        }
    }
};

Camera.takePicture() yöntemini çağırarak görüntü yakalamayı tetikleyin. Aşağıdaki örnek kod, bu yöntemin bir düğmeden (View.OnClickListener) nasıl çağrılacağını gösterir.

Kotlin

val captureButton: Button = findViewById(R.id.button_capture)
captureButton.setOnClickListener {
    // get an image from the camera
    mCamera?.takePicture(null, null, picture)
}

Java

// Add a listener to the Capture button
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(
    new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // get an image from the camera
            mCamera.takePicture(null, null, picture);
        }
    }
);

Not: Aşağıdaki örnekte bulunan mPicture üyesi, yukarıdaki örnek kodu ifade eder.

Dikkat: Uygulamanızın kullanılması bittiğinde Camera.release() öğesini çağırarak Camera nesnesini serbest bırakmayı unutmayın. Kameranın nasıl bırakılacağı hakkında bilgi edinmek için Kamerayı serbest bırakma konusuna bakın.

Video çekme

Android çerçevesini kullanarak video çekimi için Camera nesnesinin dikkatli bir şekilde yönetilmesi ve MediaRecorder sınıfıyla koordinasyon sağlanması gerekir. Camera ile video kaydederken MediaRecorder ve Camera.open() ile Camera.release() çağrılarının yanı sıra kamera donanımına da erişim izni vermek için Camera.lock() ve Camera.unlock() çağrılarını yönetmeniz gerekir.

Not: Android 4.0 (API düzeyi 14) sürümünden başlayarak Camera.lock() ve Camera.unlock() çağrıları sizin için otomatik olarak yönetilir.

Cihaz kamerasıyla resim çekmenin aksine, video çekimi çok özel bir çağrı sırası gerektirir. Uygulamanızla video çekmek ve video hazırlamak için aşağıda ayrıntılı olarak açıklanan belirli bir yürütme sırasını izlemeniz gerekir.

  1. Kamerayı Aç - Kamera nesnesinin bir örneğini almak için Camera.open() kullanın.
  2. Önizlemeyi Bağla - Camera.setPreviewDisplay() ile kameraya bir SurfaceView bağlayarak canlı kamera görüntüsü önizlemesi hazırlayın.
  3. Önizlemeyi Başlat - Canlı kamera görüntülerini göstermeye başlamak için Camera.startPreview() numaralı telefonu arayın.
  4. Video Kaydını Başlat: Videonun başarıyla kaydedilmesi için sırada aşağıdaki adımlar tamamlanmalıdır:
    1. Kameranın Kilidini Aç - Camera.unlock() numaralı telefonu arayarak MediaRecorder tarafından kullanılmak üzere kameranın kilidini açın.
    2. Configure MediaRecorder (MediaRecorder'ı Yapılandır) - Aşağıdaki MediaRecorder yöntemlerini bu sırayla çağırın. Daha fazla bilgi için MediaRecorder referans dokümanlarına bakın.
      1. setCamera() - Video çekimi için kullanılacak kamerayı ayarlayın, uygulamanızın mevcut Camera örneğini kullanın.
      2. setAudioSource(): Ses kaynağını ayarlayın, MediaRecorder.AudioSource.CAMCORDER kullanın.
      3. setVideoSource() - Video kaynağını ayarlayın, MediaRecorder.VideoSource.CAMERA kullanın.
      4. Video çıkış biçimini ve kodlamayı ayarlayın. Android 2.2 (API Düzeyi 8) ve üstü için MediaRecorder.setProfile yöntemini kullanın ve CamcorderProfile.get() ile bir profil örneği alın. Android'in 2.2 öncesi sürümleri için video çıkış biçimini ve kodlama parametrelerini ayarlamanız gerekir:
        1. setOutputFormat() - Çıkış biçimini ayarlayın, varsayılan ayarı belirtin veya MediaRecorder.OutputFormat.MPEG_4.
        2. setAudioEncoder(): Ses kodlama türünü ayarlayın, varsayılan ayarı belirtin veya MediaRecorder.AudioEncoder.AMR_NB.
        3. setVideoEncoder(): Video kodlama türünü ayarlayın, varsayılan ayarı belirtin veya MediaRecorder.VideoEncoder.MPEG_4_SP.
      5. setOutputFile() - Çıkış dosyasını ayarlayın, Medya Dosyalarını Kaydetme bölümündeki örnek yöntemden getOutputMediaFile(MEDIA_TYPE_VIDEO).toString() kullanın.
      6. setPreviewDisplay() - Uygulamanız için SurfaceView önizleme düzeni öğesini belirtin. Önizleme Önizlemesi için belirttiğiniz nesneyi kullanın.

      Dikkat: Bu MediaRecorder yapılandırma yöntemlerini bu sırayla çağırmanız gerekir. Aksi takdirde uygulamanız hatalarla karşılaşır ve kayıt işlemi başarısız olur.

    3. MediaRecorder'ı hazırlama - MediaRecorder.prepare() yöntemini çağırarak, sağlanan yapılandırma ayarlarıyla MediaRecorder'yi hazırlayın.
    4. MediaRecorder'ı Başlat - MediaRecorder.start() adlı kişiyi arayarak video kaydetmeye başlayın.
  5. Video Kaydını Durdurma: Video kaydını başarıyla tamamlamak için sırasıyla aşağıdaki yöntemleri çağırın:
    1. MediaRecorder'ı durdur - MediaRecorder.stop() numaralı telefonu arayarak video kaydını durdurun.
    2. MediaRecorder'ı Sıfırla - İsteğe bağlı olarak, MediaRecorder.reset() çağrısı yaparak kaydediciden yapılandırma ayarlarını kaldırın.
    3. MediaRecorder - MediaRecorder.release() yöntemini çağırarak MediaRecorder sürümünü bırakın.
    4. Kamerayı Kilitle: Gelecekteki MediaRecorder oturumlarında Camera.lock() numaralı telefonu arayarak kameranın kullanılabilmesi için kamerayı kilitleyin. Android 4.0 (API düzeyi 14) sürümünden başlayarak, MediaRecorder.prepare() çağrısı başarısız olmadıkça bu çağrıya gerek yoktur.
  6. Önizlemeyi Durdur - Kamerayla etkinliğiniz bittiğinde Camera.stopPreview() kullanarak önizlemeyi durdurun.
  7. Kamerayı Bırak - Diğer uygulamaların Camera.release() yöntemini çağırarak kamerayı kullanabilmesi için kamerayı serbest bırakın.

Not: Önce kamera önizlemesi oluşturmadan MediaRecorder kullanılabilir ve bu işlemin ilk birkaç adımı atlayabilirsiniz. Bununla birlikte, kullanıcılar genellikle kayda başlamadan önce önizleme görmeyi tercih ettiklerinden bu işlem burada ele alınmamaktadır.

İpucu: Uygulamanız genellikle video kaydı için kullanılıyorsa önizlemenizi başlatmadan önce setRecordingHint(boolean) değerini true olarak ayarlayın. Bu ayar, kayda başlamak için gereken süreyi azaltmaya yardımcı olabilir.

MediaRecorder'ı yapılandırma

Video kaydetmek için MediaRecorder sınıfını kullanırken yapılandırma adımlarını belirli bir sırada gerçekleştirmeniz ve ardından yapılandırmayı kontrol edip uygulamak için MediaRecorder.prepare() yöntemini çağırmanız gerekir. Aşağıdaki örnek kod, video kaydı için MediaRecorder sınıfının doğru şekilde nasıl yapılandırılıp hazırlanacağını gösterir.

Kotlin

private fun prepareVideoRecorder(): Boolean {
    mediaRecorder = MediaRecorder()

    mCamera?.let { camera ->
        // Step 1: Unlock and set camera to MediaRecorder
        camera?.unlock()

        mediaRecorder?.run {
            setCamera(camera)

            // Step 2: Set sources
            setAudioSource(MediaRecorder.AudioSource.CAMCORDER)
            setVideoSource(MediaRecorder.VideoSource.CAMERA)

            // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
            setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH))

            // Step 4: Set output file
            setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString())

            // Step 5: Set the preview output
            setPreviewDisplay(mPreview?.holder?.surface)

            setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
            setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT)
            setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT)


            // Step 6: Prepare configured MediaRecorder
            return try {
                prepare()
                true
            } catch (e: IllegalStateException) {
                Log.d(TAG, "IllegalStateException preparing MediaRecorder: ${e.message}")
                releaseMediaRecorder()
                false
            } catch (e: IOException) {
                Log.d(TAG, "IOException preparing MediaRecorder: ${e.message}")
                releaseMediaRecorder()
                false
            }
        }

    }
    return false
}

Java

private boolean prepareVideoRecorder(){

    mCamera = getCameraInstance();
    mediaRecorder = new MediaRecorder();

    // Step 1: Unlock and set camera to MediaRecorder
    mCamera.unlock();
    mediaRecorder.setCamera(mCamera);

    // Step 2: Set sources
    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
    mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

    // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
    mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));

    // Step 4: Set output file
    mediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());

    // Step 5: Set the preview output
    mediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());

    // Step 6: Prepare configured MediaRecorder
    try {
        mediaRecorder.prepare();
    } catch (IllegalStateException e) {
        Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
        releaseMediaRecorder();
        return false;
    } catch (IOException e) {
        Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
        releaseMediaRecorder();
        return false;
    }
    return true;
}

Android 2.2'den (API Düzeyi 8) önce, çıkış biçimini ve kodlama biçimi parametrelerini CamcorderProfile kullanmak yerine doğrudan ayarlamanız gerekir. Bu yaklaşım aşağıdaki kodda gösterilmektedir:

Kotlin

    // Step 3: Set output format and encoding (for versions prior to API Level 8)
    mediaRecorder?.apply {
        setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
        setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT)
        setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT)
    }

Java

    // Step 3: Set output format and encoding (for versions prior to API Level 8)
    mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
    mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);

MediaRecorder için aşağıdaki video kaydı parametrelerine varsayılan ayarlar verilmiştir ancak uygulamanız için bu ayarları düzenlemek isteyebilirsiniz:

MediaRecorder'ı başlatma ve durdurma

MediaRecorder sınıfını kullanarak video kaydını başlatıp durdururken aşağıda listelenen belirli bir sırayı uygulamanız gerekir.

  1. Kameranın kilidini Camera.unlock() ile açın
  2. MediaRecorder öğesini yukarıdaki kod örneğinde gösterildiği gibi yapılandırın
  3. MediaRecorder.start() uygulamasını kullanarak kaydı başlat
  4. Videoyu kaydedin
  5. MediaRecorder.stop() ile kaydı durdur
  6. MediaRecorder.release() ile medya kaydediciyi bırakın
  7. Camera.lock() uygulamasını kullanarak kamerayı kilitleyin

Aşağıdaki örnek kod, kamera ve MediaRecorder sınıfını kullanarak video kaydını düzgün şekilde başlatmak ve durdurmak için bir düğmenin nasıl bağlanacağını göstermektedir.

Not: Video kaydını tamamlarken kamerayı bırakmayın, aksi takdirde önizlemeniz durdurulur.

Kotlin

var isRecording = false
val captureButton: Button = findViewById(R.id.button_capture)
captureButton.setOnClickListener {
    if (isRecording) {
        // stop recording and release camera
        mediaRecorder?.stop() // stop the recording
        releaseMediaRecorder() // release the MediaRecorder object
        mCamera?.lock() // take camera access back from MediaRecorder

        // inform the user that recording has stopped
        setCaptureButtonText("Capture")
        isRecording = false
    } else {
        // initialize video camera
        if (prepareVideoRecorder()) {
            // Camera is available and unlocked, MediaRecorder is prepared,
            // now you can start recording
            mediaRecorder?.start()

            // inform the user that recording has started
            setCaptureButtonText("Stop")
            isRecording = true
        } else {
            // prepare didn't work, release the camera
            releaseMediaRecorder()
            // inform user
        }
    }
}

Java

private boolean isRecording = false;

// Add a listener to the Capture button
Button captureButton = (Button) findViewById(id.button_capture);
captureButton.setOnClickListener(
    new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (isRecording) {
                // stop recording and release camera
                mediaRecorder.stop();  // stop the recording
                releaseMediaRecorder(); // release the MediaRecorder object
                mCamera.lock();         // take camera access back from MediaRecorder

                // inform the user that recording has stopped
                setCaptureButtonText("Capture");
                isRecording = false;
            } else {
                // initialize video camera
                if (prepareVideoRecorder()) {
                    // Camera is available and unlocked, MediaRecorder is prepared,
                    // now you can start recording
                    mediaRecorder.start();

                    // inform the user that recording has started
                    setCaptureButtonText("Stop");
                    isRecording = true;
                } else {
                    // prepare didn't work, release the camera
                    releaseMediaRecorder();
                    // inform user
                }
            }
        }
    }
);

Not: Yukarıdaki örnekte prepareVideoRecorder() yöntemi, MediaRecorder'ı Yapılandırma bölümünde gösterilen örnek kodu ifade eder. Bu yöntem; kameranın kilitlenmesini, MediaRecorder örneğini yapılandırmayı ve hazırlamasını sağlar.

Kamera serbest bırakılıyor

Kameralar bir cihazdaki uygulamalar tarafından paylaşılan kaynaklardır. Uygulamanız, Camera örneğini aldıktan sonra kamerayı kullanabilir. Bu nedenle, kamera nesnesini uygulamanız kullanmayı durdurduğunda ve uygulamanız duraklatıldığında (Activity.onPause()) kısa bir süre içinde serbest bırakmaya özellikle dikkat etmeniz gerekir. Uygulamanız kamerayı düzgün bir şekilde serbest bırakmazsa, kendi uygulamanızın yaptıkları da dahil olmak üzere kameraya erişmek için sonraki tüm girişimler başarısız olur ve diğer uygulamalarınızın kapanmasına neden olabilir.

Camera nesnesinin bir örneğini serbest bırakmak için aşağıdaki örnek kodda gösterildiği gibi Camera.release() yöntemini kullanın.

Kotlin

class CameraActivity : Activity() {
    private var mCamera: Camera?
    private var preview: SurfaceView?
    private var mediaRecorder: MediaRecorder?

    override fun onPause() {
        super.onPause()
        releaseMediaRecorder() // if you are using MediaRecorder, release it first
        releaseCamera() // release the camera immediately on pause event
    }

    private fun releaseMediaRecorder() {
        mediaRecorder?.reset() // clear recorder configuration
        mediaRecorder?.release() // release the recorder object
        mediaRecorder = null
        mCamera?.lock() // lock camera for later use
    }

    private fun releaseCamera() {
        mCamera?.release() // release the camera for other applications
        mCamera = null
    }
}

Java

public class CameraActivity extends Activity {
    private Camera mCamera;
    private SurfaceView preview;
    private MediaRecorder mediaRecorder;

    ...

    @Override
    protected void onPause() {
        super.onPause();
        releaseMediaRecorder();       // if you are using MediaRecorder, release it first
        releaseCamera();              // release the camera immediately on pause event
    }

    private void releaseMediaRecorder(){
        if (mediaRecorder != null) {
            mediaRecorder.reset();   // clear recorder configuration
            mediaRecorder.release(); // release the recorder object
            mediaRecorder = null;
            mCamera.lock();           // lock camera for later use
        }
    }

    private void releaseCamera(){
        if (mCamera != null){
            mCamera.release();        // release the camera for other applications
            mCamera = null;
        }
    }
}

Dikkat: Uygulamanız, kamerayı düzgün bir şekilde serbest bırakmazsa kendi uygulamanızın yaptığı olanlar da dahil olmak üzere kameraya erişmek için sonraki tüm girişimler başarısız olur ve sizin veya diğer uygulamalarınızın kapatılmasına neden olabilir.

Medya dosyaları kaydediliyor

Kullanıcıların oluşturduğu resim ve video gibi medya dosyaları, sistem alanından tasarruf etmek ve kullanıcıların cihazları olmadan bu dosyalara erişebilmesi için cihazın harici depolama dizinine (SD Kart) kaydedilmelidir. Bir cihaza medya dosyalarını kaydetmek için pek çok olası dizin konumu vardır, ancak bir geliştirici olarak dikkate almanız gereken yalnızca iki standart konum vardır:

  • Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) - Bu yöntem, resim ve videoları kaydetmek için standart, paylaşılan ve önerilen konumu döndürür. Bu dizin paylaşılmaktadır (herkese açık). Böylece diğer uygulamalar, bu konuma kaydedilen dosyaları kolayca keşfedebilir, okuyabilir, değiştirebilir ve silebilir. Uygulamanızın yüklemesi kullanıcı tarafından kaldırılırsa bu konuma kaydedilen medya dosyaları kaldırılmaz. Kullanıcıların mevcut resimlerinin ve videolarının kesintiye uğramasını önlemek amacıyla, aşağıdaki kod örneğinde gösterildiği gibi bu dizin içinde uygulamanızın medya dosyaları için bir alt dizin oluşturmanız gerekir. Bu yöntem Android 2.2'de (API Düzeyi 8) kullanılabilir. Önceki API sürümlerinde eşdeğer çağrılar için Paylaşılan Dosyaları Kaydetme bölümüne bakın.
  • Context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) - Bu yöntem, uygulamanızla ilişkilendirilen resim ve videoları kaydetmek için standart bir konum döndürür. Uygulamanızın yüklemesi kaldırılırsa bu konuma kaydedilen tüm dosyalar kaldırılır. Bu konumdaki dosyalar için güvenlik zorunlu tutulmaz ve diğer uygulamalar dosyaları okuyabilir, değiştirebilir ve silebilir.

Aşağıdaki örnek kodda, cihazın kamerası Intent ile çağrılırken veya Kamera Uygulaması Oluşturma kapsamında kullanılabilecek bir medya dosyası için nasıl File veya Uri konumu oluşturulacağı gösterilmektedir.

Kotlin

val MEDIA_TYPE_IMAGE = 1
val MEDIA_TYPE_VIDEO = 2

/** Create a file Uri for saving an image or video */
private fun getOutputMediaFileUri(type: Int): Uri {
    return Uri.fromFile(getOutputMediaFile(type))
}

/** Create a File for saving an image or video */
private fun getOutputMediaFile(type: Int): File? {
    // To be safe, you should check that the SDCard is mounted
    // using Environment.getExternalStorageState() before doing this.

    val mediaStorageDir = File(
            Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
            "MyCameraApp"
    )
    // This location works best if you want the created images to be shared
    // between applications and persist after your app has been uninstalled.

    // Create the storage directory if it does not exist
    mediaStorageDir.apply {
        if (!exists()) {
            if (!mkdirs()) {
                Log.d("MyCameraApp", "failed to create directory")
                return null
            }
        }
    }

    // Create a media file name
    val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
    return when (type) {
        MEDIA_TYPE_IMAGE -> {
            File("${mediaStorageDir.path}${File.separator}IMG_$timeStamp.jpg")
        }
        MEDIA_TYPE_VIDEO -> {
            File("${mediaStorageDir.path}${File.separator}VID_$timeStamp.mp4")
        }
        else -> null
    }
}

Java

public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;

/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type){
      return Uri.fromFile(getOutputMediaFile(type));
}

/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
    // To be safe, you should check that the SDCard is mounted
    // using Environment.getExternalStorageState() before doing this.

    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
              Environment.DIRECTORY_PICTURES), "MyCameraApp");
    // This location works best if you want the created images to be shared
    // between applications and persist after your app has been uninstalled.

    // Create the storage directory if it does not exist
    if (! mediaStorageDir.exists()){
        if (! mediaStorageDir.mkdirs()){
            Log.d("MyCameraApp", "failed to create directory");
            return null;
        }
    }

    // Create a media file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    File mediaFile;
    if (type == MEDIA_TYPE_IMAGE){
        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
        "IMG_"+ timeStamp + ".jpg");
    } else if(type == MEDIA_TYPE_VIDEO) {
        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
        "VID_"+ timeStamp + ".mp4");
    } else {
        return null;
    }

    return mediaFile;
}

Not: Environment.getExternalStoragePublicDirectory(), Android 2.2 (API Düzeyi 8) veya sonraki sürümlerde kullanılabilir. Android'in önceki sürümlerine sahip cihazları hedefliyorsanız bunun yerine Environment.getExternalStorageDirectory() kullanın. Daha fazla bilgi için Paylaşılan Dosyaları Kaydetme konusuna bakın.

URI'nın iş profillerini desteklemesini sağlamak için önce dosya URI'sını içerik URI'sine dönüştürün. Ardından, içerik URI'sını bir Intent öğesinin EXTRA_OUTPUT öğesine ekleyin.

Android cihazlara dosya kaydetme hakkında daha fazla bilgi edinmek için Veri Depolama başlıklı makaleye göz atın.

Kamera özellikleri

Android, kamera uygulamanızla denetleyebileceğiniz resim biçimi, flaş modu, odak ayarları ve daha pek çok kamera özelliğini destekler. Bu bölümde genel kamera özellikleri listelenip bunların nasıl kullanılacağı kısaca anlatılmaktadır. Çoğu kamera özelliğine Camera.Parameters nesnesi aracılığıyla erişilebilir ve bu özellik ayarlanabilir. Ancak Camera.Parameters ürününde basit ayarlardan daha fazlasını gerektiren bazı önemli özellikler var. Bu özellikler aşağıdaki bölümlerde ele alınmıştır:

Camera.Parameters üzerinden denetlenen özelliklerin nasıl kullanılacağı hakkında genel bilgi için Kamera özelliklerini kullanma bölümünü inceleyin. Kamera parametreleri nesnesiyle kontrol edilen özelliklerin nasıl kullanılacağı hakkında daha ayrıntılı bilgi için aşağıdaki özellik listesinde yer alan bağlantıları takip ederek API referans belgelerine bakın.

Tablo 1. Yaygın olarak kullanılan kamera özellikleri, kullanıma sunuldukları Android API Düzeyi'ne göre sıralanır.

Özellik API Düzeyi Açıklama
Yüz Algılama 14 Resimlerdeki insan yüzlerini tanımlama ve bu yüzleri odaklama, ölçüm ve beyaz dengesi için kullanma
Ölçüm Alanları 14 Beyaz dengesini hesaplamak için bir resim içinde bir veya daha fazla alan belirtin
Odaklanılan Alanlar 14 Resimde, odak için kullanılacak bir veya daha fazla alan ayarlayın
White Balance Lock 14 Otomatik beyaz dengesi ayarlamalarını durdurma veya başlatma
Exposure Lock 14 Otomatik pozlama ayarlamalarını durdurma veya başlatma
Video Snapshot 14 Video çekerken fotoğraf çekme (kare yakalama)
Zaman Atlama Videosu 11 Zaman atlamalı video kaydetmek için belirli gecikmelerle kare kaydetme
Multiple Cameras 9 Ön ve arka kameralar da dahil olmak üzere bir cihazda birden fazla kamera desteği
Focus Distance 9 Kamera ile odakta olduğu görülen nesneler arasındaki mesafeleri bildirir
Zoom 8 Resim büyütmeyi ayarlayın
Exposure Compensation 8 Işığın pozlama düzeyini artır veya azalt
GPS Data 5 Görselle birlikte coğrafi konum verilerini ekleyin veya çıkarın
White Balance 5 Yakalanan görüntüdeki renk değerlerini etkileyen beyaz dengesi modunu ayarlayın
Focus Mode 5 Kameranın bir özneye (ör. otomatik, sabit, makro veya sonsuz) nasıl odaklanacağını ayarlayın
Scene Mode 5 Gece, plaj, kar veya mum ışığı sahneleri gibi belirli fotoğrafçılık durumları için hazır ayar modu uygulayın
JPEG Quality 5 JPEG resmi için sıkıştırma düzeyini ayarlayın. Bu işlem, görüntü çıkış dosyası kalitesini ve boyutunu küçültür veya artırır
Flash Mode 5 Flaşı açın, kapatın veya otomatik ayarı kullanın
Color Effects 5 Çekilen resme siyah beyaz, sepya tonu veya negatif gibi bir renk efekti uygulayın.
Anti-Banding 5 JPEG sıkıştırması nedeniyle renk gradyanlarında şerit oluşumunun etkisini azaltır
Picture Format 1 Resmin dosya biçimini belirtin
Picture Size 1 Kaydedilen resmin piksel boyutlarını belirtin

Not: Bu özellikler, donanım farklılıkları ve yazılım uygulaması nedeniyle tüm cihazlarda desteklenmez. Uygulamanızın çalıştığı cihazdaki özelliklerin kullanılabilirliğini kontrol etmeyle ilgili bilgi için Özelliklerin kullanılabilirliğini kontrol etme bölümüne bakın.

Özelliklerin kullanılabilirliği kontrol ediliyor

Android cihazlarda kamera özelliklerini kullanmak için kurulum yaparken öncelikle tüm kamera özelliklerinin tüm cihazlarda desteklenmediğidir. Ayrıca, belirli bir özelliği destekleyen cihazlar, bunları farklı düzeylerde veya farklı seçeneklerle destekleyebilir. Bu nedenle, bir kamera uygulaması geliştirirken karar verme sürecinizin bir parçası da hangi kamera özelliklerini hangi seviyede desteklemek istediğinize karar vermektir. Bu kararı verdikten sonra, kamera uygulamanıza, cihaz donanımının bu özellikleri destekleyip desteklemediğini ve bir özellik yoksa düzgün bir şekilde başarısız olup olmadığını kontrol eden bir kod eklemeyi planlamanız gerekir.

Bir kameranın parametre nesnesinin bir örneğini alarak ve ilgili yöntemleri kontrol ederek kamera özelliklerinin kullanılabilirliğini kontrol edebilirsiniz. Aşağıdaki kod örneğinde bir Camera.Parameters nesnesini nasıl edineceğiniz ve kameranın otomatik odaklama özelliğini destekleyip desteklemediğini nasıl kontrol edeceğiniz gösterilmektedir:

Kotlin

val params: Camera.Parameters? = camera?.parameters
val focusModes: List<String>? = params?.supportedFocusModes
if (focusModes?.contains(Camera.Parameters.FOCUS_MODE_AUTO) == true) {
    // Autofocus mode is supported
}

Java

// get Camera parameters
Camera.Parameters params = camera.getParameters();

List<String> focusModes = params.getSupportedFocusModes();
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
  // Autofocus mode is supported
}

Çoğu kamera özelliği için yukarıda gösterilen tekniği kullanabilirsiniz. Camera.Parameters nesnesi, bir özelliğin desteklenip desteklenmediğini (ve ne kadar destekleneceğini) belirlemek için bir getSupported...(), is...Supported() veya getMax...() yöntemi sağlar.

Uygulamanızın düzgün çalışması için belirli kamera özellikleri gerekiyorsa bunları uygulama manifest dosyanıza ekleyerek zorunlu kılabilirsiniz. Flaş ve otomatik odaklama gibi belirli kamera özelliklerinin kullanılacağını bildirdiğinizde Google Play, uygulamanızın bu özellikleri desteklemeyen cihazlara yüklenmesini kısıtlar. Uygulama manifestinizde beyan edilebilen kamera özelliklerinin listesi için manifest Özellikler Referansı'na bakın.

Kamera özelliklerini kullanma

Çoğu kamera özelliği bir Camera.Parameters nesnesi kullanılarak etkinleştirilir ve kontrol edilir. Bu nesneyi aşağıdaki örnek kodda gösterildiği gibi önce Camera nesnesinin bir örneğini alıp getParameters() yöntemini çağırarak, döndürülen parametre nesnesini değiştirerek ve ardından tekrar kamera nesnesine ayarlayarak elde edersiniz:

Kotlin

val params: Camera.Parameters? = camera?.parameters
params?.focusMode = Camera.Parameters.FOCUS_MODE_AUTO
camera?.parameters = params

Java

// get Camera parameters
Camera.Parameters params = camera.getParameters();
// set the focus mode
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
// set Camera parameters
camera.setParameters(params);

Bu teknik neredeyse tüm kamera özelliklerinde işe yarar ve parametrelerin çoğu, Camera nesnesinin bir örneğini aldıktan sonra istediğiniz zaman değiştirilebilir. Parametrelerde yapılan değişiklikler genellikle uygulamanın kamera önizlemesinde kullanıcı tarafından hemen görülebilir. Yazılım tarafında ise, kamera donanımı yeni talimatları işleyip güncellenmiş görüntü verilerini gönderirken parametre değişikliklerinin etkinleşmesi için birkaç kare geçmesi gerekebilir.

Önemli: Bazı kamera özellikleri istendiğinde değiştirilemez. Özellikle, kamera önizlemesinin boyutunu veya yönünü değiştirmek için önce önizlemeyi durdurmanız, önizleme boyutunu değiştirmeniz ve ardından önizlemeyi yeniden başlatmanız gerekir. Android 4.0 (API Düzeyi 14) sürümünden başlayarak, önizlemenin yönü, önizleme yeniden başlatılmadan değiştirilebilir.

Aşağıdakiler de dahil olmak üzere diğer kamera özelliklerinin uygulanması için daha fazla kod gerekir:

  • Ölçme ve odak alanları
  • Yüz algılama
  • Zaman atlamalı video

İlerleyen bölümlerde, bu özelliklerin nasıl uygulanacağına ilişkin kısa bir özet sunulmaktadır.

Ölçme ve odak alanları

Bazı fotoğraf senaryolarında, otomatik odaklama ve ışık ölçümü istenen sonuçları vermeyebilir. Kamera uygulamanız, Android 4.0 (API Seviyesi 14) sürümünden itibaren, uygulamanın veya kullanıcıların bir görüntüde odak veya ışık seviyesi ayarlarını belirlemek için kullanılacak alanları belirtmesine ve bu değerleri görüntü veya video çekmekte kullanılmak üzere kamera donanımına iletmesine olanak tanıyan ek kontroller sağlayabilir.

Ölçüm ve odaklama alanları, diğer kamera özelliklerine çok benzer şekilde çalışır. Çünkü bu alanları Camera.Parameters nesnesindeki yöntemlerle kontrol edebilirsiniz. Aşağıdaki kod, Camera örneği için iki ışık sayacı alanının ayarlanmasını göstermektedir:

Kotlin

// Create an instance of Camera
camera = getCameraInstance()

// set Camera parameters
val params: Camera.Parameters? = camera?.parameters

params?.apply {
    if (maxNumMeteringAreas > 0) { // check that metering areas are supported
        meteringAreas = ArrayList<Camera.Area>().apply {
            val areaRect1 = Rect(-100, -100, 100, 100) // specify an area in center of image
            add(Camera.Area(areaRect1, 600)) // set weight to 60%
            val areaRect2 = Rect(800, -1000, 1000, -800) // specify an area in upper right of image
            add(Camera.Area(areaRect2, 400)) // set weight to 40%
        }
    }
    camera?.parameters = this
}

Java

// Create an instance of Camera
camera = getCameraInstance();

// set Camera parameters
Camera.Parameters params = camera.getParameters();

if (params.getMaxNumMeteringAreas() > 0){ // check that metering areas are supported
    List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();

    Rect areaRect1 = new Rect(-100, -100, 100, 100);    // specify an area in center of image
    meteringAreas.add(new Camera.Area(areaRect1, 600)); // set weight to 60%
    Rect areaRect2 = new Rect(800, -1000, 1000, -800);  // specify an area in upper right of image
    meteringAreas.add(new Camera.Area(areaRect2, 400)); // set weight to 40%
    params.setMeteringAreas(meteringAreas);
}

camera.setParameters(params);

Camera.Area nesnesi iki veri parametresi içerir: Kameranın görüş alanı içindeki bir alanı belirtmek için kullanılan bir Rect nesnesi ve kameraya ışık ölçümü veya odak hesaplamalarında bu alanın ne kadar önem derecesi verileceğini bildiren bir ağırlık değeri.

Bir Camera.Area nesnesindeki Rect alanı, 2000 x 2000'lik bir birim ızgara üzerinde eşlenen dikdörtgen bir şekil gösterir. Aşağıdaki resimde de gösterildiği gibi -1000 ve -1000 koordinatları kamera resminin üst ve sol köşesini, 1000 ve 1000 koordinatları ise kamera görüntüsünün sağ alt köşesini temsil eder.

Şekil 1. Kırmızı çizgiler, kamera önizlemesinde Camera.Area belirtmeye yönelik koordinat sistemini gösterir. Mavi kutu, 333.333.667.667 Rect değerleriyle kamera alanının konumunu ve şeklini gösterir.

Bu koordinat sisteminin sınırları, her zaman kamera önizlemesinde görünen görüntünün dış kenarına karşılık gelir ve yakınlaştırma düzeyiyle küçültülmez veya genişlemez. Benzer şekilde, resim önizlemesinin Camera.setDisplayOrientation() kullanılarak döndürülmesi, koordinat sistemini yeniden eşleştirmez.

Yüz algılama

İnsanların bulunduğu resimlerde, yüzler genellikle resmin en önemli kısmıdır ve fotoğraf çekerken hem odak hem de beyaz dengesini belirlemek için kullanılmalıdır. Android 4.0 (API Düzeyi 14) çerçevesi, yüz tanıma teknolojisini kullanarak yüzleri tanımlamak ve resim ayarlarını hesaplamak için API'ler sağlar.

Not: Yüz algılama özelliği çalışırken setWhiteBalance(String), setFocusAreas(List<Camera.Area>) ve setMeteringAreas(List<Camera.Area>) özelliklerinin etkisi olmaz.

Kamera uygulamanızdaki yüz algılama özelliğini kullanmak için birkaç genel adım gerekir:

  • Cihazda yüz algılama özelliğinin desteklendiğinden emin olun
  • Yüz algılama dinleyicisi oluşturma
  • Yüz algılama dinleyicisini kameranızın objesine ekleyin
  • Yüz tanımayı önizlemeden sonra (ve her önizleme yeniden başlattıktan sonra) başlat

Yüz algılama özelliği tüm cihazlarda desteklenmez. getMaxNumDetectedFaces() numaralı telefonu arayarak bu özelliğin desteklenip desteklenmediğini kontrol edebilirsiniz. Bu kontrolün bir örneği aşağıdaki startFaceDetection() örnek yönteminde gösterilmektedir.

Yüz algılamaya yanıt vermek ve bildirim almak için kamera uygulamanızın yüz algılama etkinlikleri için bir dinleyici ayarlaması gerekir. Bunu yapmak için aşağıdaki örnek kodda gösterildiği gibi Camera.FaceDetectionListener arayüzünü uygulayan bir işleyici sınıfı oluşturmanız gerekir.

Kotlin

internal class MyFaceDetectionListener : Camera.FaceDetectionListener {

    override fun onFaceDetection(faces: Array<Camera.Face>, camera: Camera) {
        if (faces.isNotEmpty()) {
            Log.d("FaceDetection", ("face detected: ${faces.size}" +
                    " Face 1 Location X: ${faces[0].rect.centerX()}" +
                    "Y: ${faces[0].rect.centerY()}"))
        }
    }
}

Java

class MyFaceDetectionListener implements Camera.FaceDetectionListener {

    @Override
    public void onFaceDetection(Face[] faces, Camera camera) {
        if (faces.length > 0){
            Log.d("FaceDetection", "face detected: "+ faces.length +
                    " Face 1 Location X: " + faces[0].rect.centerX() +
                    "Y: " + faces[0].rect.centerY() );
        }
    }
}

Bu sınıfı oluşturduktan sonra, aşağıdaki örnek kodda gösterildiği gibi uygulamanızın Camera nesnesine ayarlayın:

Kotlin

camera?.setFaceDetectionListener(MyFaceDetectionListener())

Java

camera.setFaceDetectionListener(new MyFaceDetectionListener());

Uygulamanız, kamera önizlemesini her başlattığınızda (veya yeniden başlattığınızda) yüz algılama işlevini başlatmalıdır. Aşağıdaki örnek kodda gösterildiği gibi, yüz algılamayı başlatmak için bir yöntem oluşturun.

Kotlin

fun startFaceDetection() {
    // Try starting Face Detection
    val params = mCamera?.parameters
    // start face detection only *after* preview has started

    params?.apply {
        if (maxNumDetectedFaces > 0) {
            // camera supports face detection, so can start it:
            mCamera?.startFaceDetection()
        }
    }
}

Java

public void startFaceDetection(){
    // Try starting Face Detection
    Camera.Parameters params = mCamera.getParameters();

    // start face detection only *after* preview has started
    if (params.getMaxNumDetectedFaces() > 0){
        // camera supports face detection, so can start it:
        mCamera.startFaceDetection();
    }
}

Kamera önizlemesini her başlattığınızda yüz algılamayı da başlatmanız gerekir. Önizleme sınıfı oluşturma bölümünde gösterilen önizleme sınıfını kullanıyorsanız aşağıdaki örnek kodda gösterildiği gibi startFaceDetection() yönteminizi önizleme sınıfınızdaki surfaceCreated() ve surfaceChanged() yöntemlerine ekleyin.

Kotlin

override fun surfaceCreated(holder: SurfaceHolder) {
    try {
        mCamera.setPreviewDisplay(holder)
        mCamera.startPreview()

        startFaceDetection() // start face detection feature
    } catch (e: IOException) {
        Log.d(TAG, "Error setting camera preview: ${e.message}")
    }
}

override fun surfaceChanged(holder: SurfaceHolder, format: Int, w: Int, h: Int) {
    if (holder.surface == null) {
        // preview surface does not exist
        Log.d(TAG, "holder.getSurface() == null")
        return
    }
    try {
        mCamera.stopPreview()
    } catch (e: Exception) {
        // ignore: tried to stop a non-existent preview
        Log.d(TAG, "Error stopping camera preview: ${e.message}")
    }
    try {
        mCamera.setPreviewDisplay(holder)
        mCamera.startPreview()

        startFaceDetection() // re-start face detection feature
    } catch (e: Exception) {
        // ignore: tried to stop a non-existent preview
        Log.d(TAG, "Error starting camera preview: ${e.message}")
    }
}

Java

public void surfaceCreated(SurfaceHolder holder) {
    try {
        mCamera.setPreviewDisplay(holder);
        mCamera.startPreview();

        startFaceDetection(); // start face detection feature

    } catch (IOException e) {
        Log.d(TAG, "Error setting camera preview: " + e.getMessage());
    }
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {

    if (holder.getSurface() == null){
        // preview surface does not exist
        Log.d(TAG, "holder.getSurface() == null");
        return;
    }

    try {
        mCamera.stopPreview();

    } catch (Exception e){
        // ignore: tried to stop a non-existent preview
        Log.d(TAG, "Error stopping camera preview: " + e.getMessage());
    }

    try {
        mCamera.setPreviewDisplay(holder);
        mCamera.startPreview();

        startFaceDetection(); // re-start face detection feature

    } catch (Exception e){
        // ignore: tried to stop a non-existent preview
        Log.d(TAG, "Error starting camera preview: " + e.getMessage());
    }
}

Not: Bu yöntemi, startPreview() çağrısından sonra çağırmayı unutmayın. Önizleme, uygulamanızın yürütme işlemi sırasında bu noktaya kadar kullanılamayacağı için kamera uygulamanızın ana etkinliğindeki onCreate() yönteminde yüz algılamayı başlatmaya çalışmayın.

Zaman atlamalı video

Zaman atlamalı video, kullanıcıların birkaç saniye veya dakika arayla çekilen resimleri birleştiren video klipler oluşturmasına olanak tanır. Bu özellik, zaman atlamalı dizi için görüntüleri kaydetmek üzere MediaRecorder özelliğini kullanır.

MediaRecorder ile zaman atlamalı video kaydetmek için kayıt nesnesini normal bir video kaydediyormuş gibi yapılandırmanız gerekir. Saniyedeki yakalanan kare sayısını düşük bir sayıya ayarlamanız ve aşağıdaki kod örneğinde gösterildiği gibi zaman atlama kalite ayarlarından birini kullanmanız gerekir.

Kotlin

mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_TIME_LAPSE_HIGH))
mediaRecorder.setCaptureRate(0.1) // capture a frame every 10 seconds

Java

// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_TIME_LAPSE_HIGH));
...
// Step 5.5: Set the video capture rate to a low number
mediaRecorder.setCaptureRate(0.1); // capture a frame every 10 seconds

Bu ayarlar, MediaRecorder için daha geniş bir yapılandırma prosedürünün bir parçası olarak yapılmalıdır. Tam yapılandırma kodu örneği için MediaRecorder'ı Yapılandırma'ya bakın. Yapılandırma tamamlandıktan sonra video kaydını, normal bir video klip kaydediyormuş gibi başlatırsınız. MediaRecorder uygulamasını yapılandırma ve çalıştırma hakkında daha fazla bilgi için Video çekme bölümüne bakın.

Kamera2Video ve HdrViewfinder örnekleri, bu sayfada ele alınan API'lerin kullanımını daha ayrıntılı bir şekilde gösterir.

İzin gerektiren kamera alanları

Android 10 (API düzeyi 29) veya sonraki sürümleri çalıştıran uygulamalar, getCameraCharacteristics() yönteminin döndürdüğü aşağıdaki alanların değerlerine erişebilmek için CAMERA iznine sahip olmalıdır:

  • LENS_POSE_ROTATION
  • LENS_POSE_TRANSLATION
  • LENS_INTRINSIC_CALIBRATION
  • LENS_RADIAL_DISTORTION
  • LENS_POSE_REFERENCE
  • LENS_DISTORTION
  • LENS_INFO_HYPERFOCAL_DISTANCE
  • LENS_INFO_MINIMUM_FOCUS_DISTANCE
  • SENSOR_REFERENCE_ILLUMINANT1
  • SENSOR_REFERENCE_ILLUMINANT2
  • SENSOR_CALIBRATION_TRANSFORM1
  • SENSOR_CALIBRATION_TRANSFORM2
  • SENSOR_COLOR_TRANSFORM1
  • SENSOR_COLOR_TRANSFORM2
  • SENSOR_FORWARD_MATRIX1
  • SENSOR_FORWARD_MATRIX2

Ek örnek kod

Örnek uygulamalar indirmek için Kamera2Basic örneğine ve Resmi CameraX örnek uygulamasına bakın.