Android çerçevesi, cihazlarda bulunan çeşitli kameralar ve kamera özellikleri için destek içerir. Bu sayede uygulamalarınızda fotoğraf ve video çekebilirsiniz. Bu belgede, resim ve video çekmeye yönelik hızlı ve basit bir yaklaşım ele alınmakta ve kullanıcılarınız için özel kamera deneyimleri oluşturmaya yönelik gelişmiş bir yaklaşım özetlenmektedir.
Not:
Bu sayfada, desteği sonlandırılan
Camera
sınıfı açıklanmaktadır. CameraX Jetpack kitaplığını veya belirli kullanım alanları için camera2 sınıfını kullanmanızı öneririz. Hem CameraX hem de Camera2, Android 5.0 (API düzeyi 21) ve sonraki sürümlerde çalışır.
Aşağıdaki ilgili kaynaklara göz atın:
Dikkat edilmesi gereken noktalar
Uygulamanızın Android cihazlardaki kameraları kullanmasını etkinleştirmeden önce uygulamanızın bu donanım özelliğini nasıl kullanmayı planladığıyla ilgili birkaç soruyu göz önünde bulundurmanız gerekir.
- Kamera Şartı: Kamera kullanımı, uygulamanız için o kadar önemli mi ki uygulamanızın kamerası olmayan bir cihaza yüklenmesini istemiyorsunuz? Bu durumda, manifest dosyanızda kamera şartını beyan etmeniz gerekir.
- Hızlı Resim veya Özelleştirilmiş Kamera: Uygulamanız kamerayı nasıl kullanacak? Yalnızca hızlı bir fotoğraf veya video klip çekmekle mi ilgileniyorsunuz yoksa uygulamanız kameraları kullanmanın yeni bir yolunu mu sunacak? Hızlı bir şekilde fotoğraf veya video çekmek için Mevcut Kamera Uygulamalarını Kullanma başlıklı makaleyi inceleyin. Özelleştirilmiş bir kamera özelliği geliştirmek için Kamera Uygulaması Oluşturma bölümüne göz atın.
- Ön Plan Hizmetleri Şartı: Uygulamanız kamerayla ne zaman etkileşim kuruyor? 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 kullanmanız gerekir.
- Depolama: Uygulamanızın oluşturduğu resimler veya videolar yalnızca uygulamanız tarafından mı görülecek yoksa Galeri gibi diğer uygulamaların ya da diğer medya ve sosyal medya uygulamalarının kullanabilmesi için paylaşılacak mı? Uygulamanız kaldırılsa bile resim ve videoların kullanılabilir olmasını istiyor musunuz? Bu seçenekleri nasıl uygulayacağınızı öğrenmek için Medya Dosyalarını Kaydetme bölümüne göz atın.
Temel özellikler
Android çerçevesi, android.hardware.camera2 API'si veya kamera Intent aracılığıyla resim ve video çekmeyi destekler. İlgili sınıflar şunlardır:
android.hardware.camera2- Bu paket, cihaz kameralarını kontrol etmek için kullanılan birincil API'dir. Kamera uygulaması geliştirirken fotoğraf veya video çekmek için kullanılabilir.
Camera- Bu sınıf, cihaz kameralarını kontrol etmek için kullanılan eski ve kullanımdan kaldı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.
IntentMediaStore.ACTION_IMAGE_CAPTUREveyaMediaStore.ACTION_VIDEO_CAPTUREintent işlemi türü,Cameranesnesi doğrudan kullanılmadan resim veya video çekmek için kullanılabilir.
Manifest beyanları
Camera API ile uygulamanızı geliştirmeye başlamadan önce manifest dosyanızda kamera donanımının ve diğer ilgili özelliklerin kullanılmasına izin veren uygun beyanların bulunduğundan emin olmanız gerekir.
- Kamera İzni: Uygulamanızın, cihaz kamerasını kullanmak için izin istemesi gerekir.
<uses-permission android:name="android.permission.CAMERA" />
Not: Kamerayı mevcut bir kamera uygulamasını çağırarak kullanıyorsanız uygulamanızın bu izni istemesi gerekmez.
- Kamera Özellikleri: Uygulamanızın kamera özelliklerinin kullanımını da beyan etmesi gerekir. Ö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 eklediğinizde Google Play, uygulamanızın kamerası olmayan veya belirttiğiniz kamera özelliklerini desteklemeyen cihazlara yüklenmesini engeller. Google Play ile özelliğe dayalı filtrelemeyi kullanma hakkında daha fazla bilgi için Google Play ve Özelliğe Dayalı Filtreleme başlıklı makaleyi inceleyin.
Uygulamanızın düzgün çalışması için kamera veya kamera özelliği kullanılabiliyor ancak gerekli değilse bunu manifest dosyasında
android:requiredözelliğini ekleyipfalseolarak ayarlayarak belirtmeniz gerekir:<uses-feature android:name="android.hardware.camera" android:required="false" />
- Depolama İzni: Uygulamanız Android 10'u (API düzeyi 29) veya daha eski bir sürümü hedefliyor ve manifest dosyasında aşağıdakileri belirtiyorsa cihazın harici depolama alanına (SD kart) resim veya video kaydedebilir.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- Ses Kaydı İzni: Video kaydıyla ses kaydetmek için uygulamanızın ses kaydı izni istemesi gerekir.
<uses-permission android:name="android.permission.RECORD_AUDIO" />
-
Konum İzni: Uygulamanız resimleri GPS konum bilgileriyle etiketliyorsa
ACCESS_FINE_LOCATIONiznini istemeniz gerekir. Uygulamanız Android 5.0 (API düzeyi 21) veya sonraki sürümleri 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 başlıklı makaleyi inceleyin.
Mevcut kamera uygulamalarını kullanma
Uygulamanızda çok fazla ek kod kullanmadan fotoğraf veya video çekmeyi etkinleştirmenin hızlı bir yolu, mevcut bir Android kamera uygulamasını çağırmak için Intent kullanmaktır.
Ayrıntılar, Basit Bir Şekilde Fotoğraf Çekme ve Basit Bir Şekilde Video Kaydetme 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 fotoğraf çekme kodunuzu yazmak, kullanıcılarınız için daha ilgi çekici bir deneyim sunabilir.
Not: Aşağıdaki kılavuz, eski ve kullanımdan kaldırılmış Camera
API içindir. Yeni veya gelişmiş kamera uygulamaları için daha yeni olan android.hardware.camera2 API'nin kullanılması önerilir.
Uygulamanız için özel bir kamera arayüzü oluşturmanın genel adımları şunlardır:
- Kamerayı Algılama ve Kameraya Erişme: Kamera olup olmadığını kontrol etmek ve erişim istemek için kod oluşturun.
- Önizleme sınıfı oluşturma:
SurfaceViewsınıfını genişleten veSurfaceHolderarayüzünü uygulayan bir kamera önizleme sınıfı oluşturun. Bu sınıf, kameradan gelen canlı görüntüleri önizler. - Önizleme Düzeni Oluşturma: Kamera önizleme sınıfını oluşturduktan sonra, önizlemeyi ve istediğiniz kullanıcı arayüzü kontrollerini içeren bir görünüm düzeni oluşturun.
- Yakalamak için İşleyicileri Ayarlama: Arayüz kontrolleriniz için işleyicileri bağlayarak kullanıcı işlemlerine (ör. bir düğmeye basma) yanıt olarak resim veya video çekmeyi başlatın.
- Çekim ve Dosyaya Kaydetme: Resim veya video çekme ve çıkışı kaydetme kodunu ayarlayın.
- Kamerayı serbest bırakma: Uygulamanız, kamerayı kullandıktan sonra diğer uygulamaların kullanabilmesi için düzgün şekilde serbest bırakmalıdır.
Kamera donanımı, uygulamanızın kamerayı 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şimin nasıl isteneği, resim veya video çekme ve uygulamanız kamerayı kullanmayı bitirdiğinde kameranın nasıl serbest bırakılacağı açıklanmaktadır.
Dikkat: Uygulamanız Cameranesnesini kullanmayı bitirdiğinde
Camera.release() işlevini çağırarak nesneyi serbest bırakmayı unutmayın. Uygulamanız kamerayı düzgün şekilde serbest bırakmazsa kendi uygulamanızın erişim denemeleri de dahil olmak üzere kameraya erişmeye yönelik tüm sonraki denemeler başarısız olur ve uygulamanızın veya diğer uygulamaların kapatılmasına neden olabilir.
Kamera donanımı algılanıyor
Uygulamanız, manifest beyanı kullanarak özel olarak kamera gerektirmiyorsa çalışma zamanında kamera olup olmadığını kontrol etmeniz gerekir. Bu kontrolü yapmak 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 bulunabilir. Örneğin, fotoğraf çekmek için arka kamera ve görüntülü görüşmeler için ön kamera kullanılabilir. Android 2.3 (API düzeyi 9) ve sonraki sürümlerde, Camera.getNumberOfCameras() yöntemini kullanarak cihazda bulunan kamera sayısını kontrol edebilirsiniz.
Kameralara erişme
Uygulamanızın çalıştığı cihazda kamera olduğunu belirlediyseniz bir Camera örneği alarak kameraya erişim isteğinde bulunmanız gerekir (kameraya erişmek için intent kullanmıyorsanız).
Birincil kameraya erişmek için Camera.open() yöntemini kullanın ve aşağıdaki kodda gösterildiği gibi tüm 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 her zaman istisnaları kontrol edin. Kamera kullanımda veya mevcut değilse istisnaların kontrol edilmemesi, uygulamanızın sistem tarafından kapatılmasına neden olur.
Android 2.3 (API düzeyi 9) veya sonraki sürümlerin yüklü olduğu 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 özelliklerini kontrol etme
Bir kameraya erişim elde ettikten sonra Camera.getParameters() yöntemini kullanarak ve döndürülen Camera.Parameters nesnesinde desteklenen özellikleri kontrol ederek kameranın özellikleri hakkında daha fazla bilgi edinebilirsiniz. API düzeyi 9 veya daha yüksek bir sürüm kullanırken kameranın cihazın önünde mi yoksa arkasında mı olduğunu ve görüntünün yönünü belirlemek için Camera.getCameraInfo() kullanın.
Önizleme sınıfı oluşturma
Kullanıcıların etkili bir şekilde fotoğraf veya video çekebilmesi için cihaz kamerasının gördüklerini görebilmesi gerekir. Kamera önizleme sınıfı, kameradan gelen canlı görüntü verilerini görüntüleyebilen bir SurfaceView. Bu sayede kullanıcılar, resim veya video çekebilir.
Aşağıdaki örnek kodda, View düzenine dahil edilebilecek temel bir kamera önizleme sınıfının nasıl oluşturulacağı gösterilmektedir. Bu sınıf, kamera önizleme girişini atamak için gereken görünümü oluşturma ve yok etme geri çağırma etkinliklerini yakalamak amacıyla SurfaceHolder.Callback sınıfını uygular.
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 istiyorsanız bunu yukarıdaki yorumlarda belirtildiği gibi surfaceChanged() yönteminde ayarlayın. Önizleme boyutunu ayarlarken getSupportedPreviewSizes() değerlerini kullanmanız gerekir.
setPreviewSize() yönteminde rastgele değerler ayarlamayın.
Not:
Android 7.0 (API düzeyi 24) ve sonraki sürümlerde
Çoklu Pencere özelliğinin kullanıma sunulmasıyla birlikte, setDisplayOrientation() yöntemini çağırdıktan 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, geniş bir kamera önizlemesini dikey düzene sığdırmanız gerekebilir. Bunun için sinemaskop düzenini kullanabilirsiniz.
Ö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 diğer kullanıcı arayüzü kontrolleriyle birlikte bir etkinliğin düzenine yerleştirilmelidir. Bu bölümde, önizleme için temel bir düzen ve etkinliğin nasıl oluşturulacağı gösterilmektedir.
Aşağıdaki düzen kodu, kamera önizlemesini görüntülemek için kullanılabilecek çok basit bir görünüm sağlar. Bu örnekte FrameLayout öğesi, kamera önizleme sınıfının kapsayıcısıdır. Bu düzen türü, canlı kamera önizleme resimlerinin ü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üzende yatay (manzara) düzen belirtilir ve aşağıdaki kod, uygulamanın yönünü yatay olarak sabitler. Kamera önizlemesini oluşturmayı kolaylaştırmak için manifest dosyanıza aşağıdakileri ekleyerek uygulamanızın önizleme etkinliği 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) itibaren, önizleme resminin dönüşünü ayarlamak için setDisplayOrientation() yöntemini kullanabilirsiniz. Kullanıcı telefonu yeniden yönlendirdiğinde ö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, yönü değiştirin ve ardından Camera.startPreview() ile önizlemeyi tekrar başlatın.
Kamera görünümünüzün 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 kamerayı serbest bırakmalı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 bir 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.
Resim çekme
Önizleme sınıfı ve bunu görüntüleyecek bir görünüm düzeni oluşturduktan sonra uygulamanızla görüntü yakalamaya başlayabilirsiniz. Uygulama kodunuzda, kullanıcı arayüzü kontrollerinizin fotoğraf çekerek kullanıcı işlemine yanıt vermesi için dinleyiciler ayarlamanız gerekir.
Resim almak için Camera.takePicture() yöntemini kullanın. Bu yöntem, kameradan veri alan üç parametre kullanır.
JPEG biçiminde veri almak için görüntü verilerini alıp bir dosyaya yazacak bir Camera.PictureCallback arayüzü uygulamanız gerekir. Aşağıdaki kodda, kameradan alınan bir resmi kaydetmek için Camera.PictureCallback arayüzünün temel bir uygulaması gösterilmektedir.
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ü yakalama işlemini tetikleyin. Aşağıdaki örnek kodda, bu yöntemin bir düğmeden View.OnClickListener nasıl çağrılacağı gösterilmektedir.
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 örnekteki mPicture üyesi, yukarıdaki örnek koda atıfta bulunur.
Dikkat: Uygulamanız Cameranesnesini kullanmayı bitirdiğinde
Camera.release() işlevini çağırarak nesneyi serbest bırakmayı unutmayın. Kamerayı nasıl serbest bırakacağınız hakkında bilgi için Kamerayı serbest bırakma bölümünü inceleyin.
Video çekme
Android çerçevesini kullanarak video yakalama, Camera nesnesinin dikkatli bir şekilde yönetilmesini ve MediaRecorder sınıfıyla koordinasyonu gerektirir. Camera ile video kaydederken Camera.open() ve Camera.release() çağrılarının yanı sıra MediaRecorder uygulamasının kamera donanımına erişmesine izin vermek için Camera.lock() ve Camera.unlock() çağrılarını yönetmeniz gerekir.
Not: Android 4.0'dan (API düzeyi 14) itibaren Camera.lock() ve Camera.unlock() çağrıları sizin için otomatik olarak yönetilir.
Cihaz kamerasıyla fotoğraf çekmekten farklı olarak, video çekmek için çok özel bir çağrı sırası gerekir. Uygulamanızla video çekmek ve hazırlamak için aşağıda ayrıntılı olarak açıklandığı gibi belirli bir yürütme sırasını izlemeniz gerekir.
- Kamerayı açma: Kamera nesnesinin bir örneğini almak için
Camera.open()kullanın. - Önizlemeyi Bağla:
Camera.setPreviewDisplay()kullanarak kameraya birSurfaceViewbağlayarak canlı kamera görüntüsü önizlemesi hazırlayın. - Önizlemeyi Başlat: Canlı kamera görüntülerini göstermeye başlamak için
Camera.startPreview()yöntemini çağırın. - Video kaydetmeye başlama: Videonun başarıyla kaydedilmesi için aşağıdaki adımların sırayla tamamlanması gerekir:
- Kameranın kilidini açma:
Camera.unlock()yöntemini çağırarak kameranın kilidiniMediaRecordertarafından kullanılmak üzere açın. - MediaRecorder'ı yapılandırma: Aşağıdaki
MediaRecorderyöntemleri bu sırayla çağırın. Daha fazla bilgi içinMediaRecorderreferans belgelerini inceleyin.setCamera(): Kamerayı video çekimi için kullanılacak şekilde ayarlayın, uygulamanızın mevcutCameraörneğini kullanın.setAudioSource()- Ses kaynağını ayarlayın,MediaRecorder.AudioSource.CAMCORDERkullanın.setVideoSource()- Video kaynağını ayarlamak içinMediaRecorder.VideoSource.CAMERAkullanın.- Video çıkış biçimini ve kodlamasını ayarlayın. Android 2.2 (API düzeyi 8) ve sonraki sürümler için
MediaRecorder.setProfileyöntemini kullanın veCamcorderProfile.get()kullanarak bir profil örneği alın. Android'in 2.2'den önceki sürümlerinde video çıkış biçimini ve kodlama parametrelerini ayarlamanız gerekir:setOutputFormat(): Çıkış biçimini ayarlayın, varsayılan ayarı veyaMediaRecorder.OutputFormat.MPEG_4değerini belirtin.setAudioEncoder(): Ses kodlama türünü ayarlayın, varsayılan ayarı veyaMediaRecorder.AudioEncoder.AMR_NBdeğerini belirtin.setVideoEncoder(): Video kodlama türünü ayarlayın, varsayılan ayarı veyaMediaRecorder.VideoEncoder.MPEG_4_SPdeğerini belirtin.
setOutputFile()- Çıkış dosyasını ayarlayın. Medya Dosyalarını Kaydetme bölümündeki örnek yöntemdengetOutputMediaFile(MEDIA_TYPE_VIDEO).toString()kullanın.setPreviewDisplay(): Uygulamanız içinSurfaceViewönizleme düzeni öğesini belirtin. Connect Preview için belirttiğiniz nesneyi kullanın.
Dikkat: Bu
MediaRecorderyapılandırma yöntemlerini bu sırayla çağırmanız gerekir. Aksi takdirde uygulamanızda hatalar oluşur ve kayıt başarısız olur. - MediaRecorder'ı hazırlama:
MediaRecorder.prepare()yöntemini çağırarakMediaRecordernesnesini sağlanan yapılandırma ayarlarıyla hazırlayın. - MediaRecorder'ı başlatma:
MediaRecorder.start()yöntemini çağırarak video kaydetmeye başlayın.
- Kameranın kilidini açma:
- Video kaydını durdurma: Video kaydını başarıyla tamamlamak için aşağıdaki yöntemleri sırayla çağırın:
- MediaRecorder'ı durdurma:
MediaRecorder.stop()yöntemini çağırarak video kaydını durdurun. - MediaRecorder'ı sıfırlama: İsteğe bağlı olarak,
MediaRecorder.reset()yöntemini çağırarak yapılandırma ayarlarını kaydediciden kaldırabilirsiniz. - MediaRecorder'ı serbest bırakma:
MediaRecorder.release()yöntemini çağırarakMediaRecordernesnesini serbest bırakın. - Kamerayı kilitleme: Kamerayı kilitleyerek gelecekteki
MediaRecorderoturumlarınınCamera.lock()yöntemini çağırarak kamerayı kullanmasını sağlayın. Android 4.0'dan (API düzeyi 14) itibaren,MediaRecorder.prepare()çağrısı başarısız olmadığı sürece bu çağrı gerekli değildir.
- MediaRecorder'ı durdurma:
- Önizlemeyi durdurma: Etkinliğiniz kamerayı kullanmayı bitirdiğinde
Camera.stopPreview()yöntemini kullanarak önizlemeyi durdurun. - Release Camera:
Camera.release()yöntemini çağırarak kamerayı serbest bırakın. Böylece diğer uygulamalar kamerayı kullanabilir.
Not: Önce kamera önizlemesi oluşturmadan MediaRecorder
kullanabilir ve bu işlemin ilk birkaç adımını atlayabilirsiniz. Ancak kullanıcılar genellikle kayda başlamadan önce önizleme görmeyi tercih ettiğinden bu süreç burada ele alınmamaktadır.
İpucu: Uygulamanız genellikle video kaydetmek için kullanılıyorsa önizlemenizi başlatmadan önce setRecordingHint(boolean) değerini true olarak ayarlayın. Bu ayar, kayda başlama süresini kısaltmaya 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ırayla uygulamanız ve ardından yapılandırmayı kontrol edip uygulamak için MediaRecorder.prepare() yöntemini çağırmanız gerekir. Aşağıdaki örnek kodda, MediaRecorder sınıfının video kaydı için nasıl doğru şekilde yapılandırılacağı ve hazırlanacağı gösterilmektedir.
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) önceki sürümlerde, CamcorderProfile kullanmak yerine çıkış biçimi ve kodlama biçimi parametrelerini 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 atanır ancak uygulamanız için bu ayarları düzenlemek isteyebilirsiniz:
setVideoEncodingBitRate()setVideoSize()setVideoFrameRate()setAudioEncodingBitRate()setAudioChannels()setAudioSamplingRate()
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ı izlemeniz gerekir.
- Kameranın kilidini
Camera.unlock()ile açın MediaRecorderöğesini yukarıdaki kod örneğinde gösterildiği gibi yapılandırın.MediaRecorder.start()kullanarak kayda başlama- Videoyu kaydetme
MediaRecorder.stop()kullanarak kaydı durdurmaMediaRecorder.release()ile medya kaydediciyi serbest bırakmaCamera.lock()kullanarak kamerayı kilitleyin
Aşağıdaki örnek kodda, kamerayı ve MediaRecorder sınıfını kullanarak video kaydını düzgün bir şekilde başlatıp durdurmak için bir düğmenin nasıl bağlanacağı gösterilmektedir.
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 koda atıfta bulunur. Bu yöntem, kamerayı kilitleme, MediaRecorder örneğini yapılandırma ve hazırlama işlemlerini gerçekleştirir.
Kamerayı serbest bırakma
Kameralar, cihazdaki uygulamalar tarafından paylaşılan bir kaynaktır. Uygulamanız, Camera örneği aldıktan sonra kamerayı kullanabilir. Uygulamanız kamerayı kullanmayı bıraktığında ve uygulamanız duraklatıldığında (Activity.onPause()) kamera nesnesini serbest bırakmaya özellikle dikkat etmeniz gerekir. Uygulamanız kamerayı düzgün şekilde serbest bırakmazsa kendi uygulamanızın erişim denemeleri de dahil olmak üzere kameraya erişmeye yönelik tüm sonraki denemeler başarısız olur ve uygulamanızın veya diğer uygulamaların kapatılmasına neden olabilir.
Camera nesnesinin bir örneğini yayınlamak 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 şekilde serbest bırakmazsa kendi uygulamanızın erişim denemeleri de dahil olmak üzere kameraya erişmeye yönelik tüm sonraki denemeler başarısız olur ve uygulamanızın veya diğer uygulamaların kapatılmasına neden olabilir.
Medya dosyaları kaydediliyor
Kullanıcılar tarafından oluşturulan resim ve video gibi medya dosyaları, sistem alanından tasarruf etmek ve kullanıcıların bu dosyalara cihazları olmadan erişebilmelerini sağlamak için cihazın harici depolama dizinine (SD kart) kaydedilmelidir. Bir cihazda medya dosyalarını kaydetmek için birçok dizin konumu olabilir ancak 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şıldığı (herkese açık) için diğer uygulamalar bu konumda kayıtlı dosyaları kolayca bulabilir, okuyabilir, değiştirebilir ve silebilir. Uygulamanız kullanıcı tarafından kaldırılırsa bu konuma kaydedilen medya dosyaları silinmez. Kullanıcıların mevcut resim ve videolarına müdahale etmemek için aşağıdaki kod örneğinde gösterildiği gibi bu dizinde 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ümlerindeki 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şkili resim ve videoları kaydetmek için standart bir konum döndürür. Uygulamanız kaldırılırsa bu konuma kaydedilen tüm dosyalar silinir. Bu konumdaki dosyalar için güvenlik uygulanmaz ve diğer uygulamalar bu dosyaları okuyabilir, değiştirebilir ve silebilir.
Aşağıdaki örnek kodda, bir cihazın kamerasını Intent ile çağırırken veya Kamera Uygulaması Oluşturma kapsamında kullanılabilecek bir medya dosyası için File veya Uri konumunun nasıl 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ümlerini çalıştıran cihazları hedefliyorsanız bunun yerine Environment.getExternalStorageDirectory() kullanın. Daha fazla bilgi için Paylaşılan dosyaları kaydetme başlıklı makaleyi inceleyin.
URI'nin iş profillerini desteklemesi için önce
dosya URI'sini içerik URI'sine dönüştürün. Ardından, içerik URI'sini bir Intent öğesinin EXTRA_OUTPUT öğesine ekleyin.
Android cihazlarda dosya kaydetme hakkında daha fazla bilgi için Veri Depolama başlıklı makaleyi inceleyin.
Kamera özellikleri
Android; resim biçimi, flaş modu, odak ayarları ve daha birçok kamera özelliğini kamera uygulamanızla kontrol etmenize olanak tanır. Bu bölümde, yaygın kamera özellikleri listelenmekte ve bunların nasıl kullanılacağı kısaca açıklanmaktadır. Çoğu kamera özelliğine Camera.Parameters nesnesi kullanılarak erişilebilir ve ayarlanabilir. Ancak Camera.Parameters'te basit ayarlardan daha fazlasını gerektiren birkaç önemli özellik vardır. Bu özellikler aşağıdaki bölümlerde ele alınmıştır:
Camera.Parameters üzerinden kontrol edilen özelliklerin nasıl kullanılacağı hakkında genel bilgi için Kamera özelliklerini kullanma bölümünü inceleyin. Kamera parametreleri nesnesi aracılığıyla kontrol edilen özelliklerin nasıl kullanılacağı hakkında daha ayrıntılı bilgi için aşağıdaki özellik listesinde bulunan bağlantıları kullanarak API referans dokümanlarına gidin.
Tablo 1. Kullanıma sunuldukları Android API düzeyine göre sıralanmış yaygın kamera özellikleri.
| Özellik | API Seviyesi | Açıklama |
|---|---|---|
| Yüz Algılama | 14 | Resimdeki insan yüzlerini tanımlayıp odaklama, ölçüm ve beyaz dengesi için kullanma |
| Ölçüm Alanları | 14 | Beyaz dengesini hesaplamak için resim içinde bir veya daha fazla alan belirtme |
| Odaklanılan Alanlar | 14 | Odaklanmak için bir resim içinde bir veya daha fazla alan belirleyin. |
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 Atlamalı Video | 11 | Zaman atlamalı video kaydetmek için kareleri belirli gecikmelerle kaydedin |
Multiple Cameras |
9 | Ön ve arka kameralar dahil olmak üzere bir cihazda birden fazla kamera desteği |
Focus Distance |
9 | Kamera ile odakta görünen nesneler arasındaki mesafeleri bildirir. |
Zoom |
8 | Resim büyütme ayarı |
Exposure
Compensation |
8 | Işık pozlama seviyesini artırma veya azaltma |
GPS Data |
5 | Resme coğrafi konum verilerini ekleme veya eklememe |
White Balance |
5 | Çekilen resimdeki renk değerlerini etkileyen beyaz dengesi modunu ayarlayın. |
Focus Mode |
5 | Kameranın bir nesneye nasıl odaklanacağını (ör. otomatik, sabit, makro veya sonsuz) ayarlayın. |
Scene Mode |
5 | Gece, plaj, kar veya mum ışığı sahneleri gibi belirli fotoğrafçılık durumları için hazır ayar modunu uygulama |
JPEG Quality |
5 | JPEG resimlerin sıkıştırma düzeyini ayarlayarak resim çıkış dosyasının kalitesini ve boyutunu artırın veya azaltın. |
Flash Mode |
5 | Flaşı açma, kapatma veya otomatik ayarı kullanma |
Color Effects |
5 | Çekilen görüntüye siyah beyaz, sepya tonu veya negatif gibi bir renk efekti uygulayın. |
Anti-Banding |
5 | JPEG sıkıştırması nedeniyle renk gradyanlarında oluşan bantlanma etkisini azaltır. |
Picture Format |
1 | Resmin dosya biçimini belirtme |
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ığı cihazda özelliklerin kullanılabilirliğini kontrol etme hakkında bilgi için Özellik kullanılabilirliğini kontrol etme başlıklı makaleyi inceleyin.
Özelliklerin kullanılabilirlik durumunu kontrol etme
Android cihazlarda kamera özelliklerini kullanmaya başlarken öncelikle tüm kamera özelliklerinin tüm cihazlarda desteklenmediğini bilmeniz gerekir. Ayrıca, belirli bir özelliği destekleyen cihazlar bu özelliği farklı düzeylerde veya farklı seçeneklerle destekleyebilir. Bu nedenle, kamera uygulaması geliştirirken karar verme sürecinizin bir parçası da hangi kamera özelliklerini ne düzeyde desteklemek istediğinize karar vermektir. Bu kararı verdikten sonra, kamera uygulamanıza cihaz donanımının bu özellikleri destekleyip desteklemediğini kontrol eden ve bir özellik mevcut değilse düzgün bir şekilde başarısız olan kod eklemeyi planlamalısınız.
Kamera özelliklerinin kullanılabilirliğini kontrol etmek için kameranın parametre nesnesinin bir örneğini alıp ilgili yöntemleri kontrol edebilirsiniz. Aşağıdaki kod örneğinde, Camera.Parameters nesnesinin nasıl alınacağı ve kameranın otomatik odaklama özelliğini destekleyip desteklemediğinin nasıl kontrol edileceği 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 }
Yukarıda gösterilen tekniği çoğu kamera özelliği için kullanabilirsiniz. Camera.Parameters nesnesi, bir özelliğin desteklenip desteklenmediğini (ve ne ölçüde desteklendiğini) belirlemek için getSupported...(), is...Supported() veya getMax...() yöntemini 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ımını beyan ettiğinizde Google Play, uygulamanızın bu özellikleri desteklemeyen cihazlara yüklenmesini kısıtlar. Uygulama manifestinizde beyan edilebilecek kamera özelliklerinin listesi için manifest Özellikler Referansı'na bakın.
Kamera özelliklerini kullanma
Çoğu kamera özelliği, Camera.Parameters nesnesi kullanılarak etkinleştirilir ve kontrol edilir. Bu nesneyi elde etmek için önce Camera nesnesinin bir örneğini almanız, getParameters() yöntemini çağırmanız, döndürülen parametre nesnesini değiştirmeniz ve ardından aşağıdaki örnek kodda gösterildiği gibi kamera nesnesine geri ayarlamanız gerekir:
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 özellikleri için kullanılabilir ve çoğu parametre, Camera nesnesinin bir örneğini aldıktan sonra herhangi bir zamanda 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, kamera donanımı yeni talimatları işleyip güncellenmiş görüntü verilerini gönderdiğinden parametre değişikliklerinin geçerlilik kazanması birkaç kare sürebilir.
Önemli: Bazı kamera özellikleri isteğe bağlı olarak 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) ile başlayarak önizleme yönü, önizleme yeniden başlatılmadan değiştirilebilir.
Diğer kamera özelliklerini uygulamak için daha fazla kod gerekir. Bu özellikler şunlardır:
- Ölçüm ve odak alanları
- Yüz algılama
- Zaman atlamalı video
Aşağıdaki bölümlerde bu özelliklerin nasıl uygulanacağına dair kısa bir özet verilmiştir.
Ölçüm ve odak alanları
Bazı fotoğrafçılık senaryolarında otomatik odaklama ve ışık ölçümü istenen sonuçları vermeyebilir. Android 4.0'dan (API düzeyi 14) itibaren kamera uygulamanız, uygulamanızı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ü ya da video yakalamada 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. Bunları Camera.Parameters nesnesindeki yöntemlerle kontrol edersiniz. Aşağıdaki kodda, bir Camera örneği için iki ışık ölçüm alanının nasıl ayarlanacağı gösterilmektedir:
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çinde bir alan belirtmek için kullanılan Rect nesnesi ve kameraya, ışık ölçümü veya odak hesaplamalarında bu alana ne düzeyde önem verilmesi gerektiğini belirten bir ağırlık değeri.
Camera.Area nesnesindeki Rect alanı, 2.000 x 2.000 birimlik bir ızgarada eşlenen dikdörtgen bir şekli tanımlar. Aşağıdaki resimde gösterildiği gibi, -1000, -1000 koordinatları kamera görüntüsünün sol üst köşesini, 1000, 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 belirtmek için kullanılan koordinat sistemini gösterir. Mavi kutu, Rect değerleri 333,333,667,667 olan bir 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 seviyesiyle küçülmez veya genişlemez. Benzer şekilde, Camera.setDisplayOrientation() kullanarak resim önizlemesini döndürmek koordinat sistemini yeniden eşlemez.
Yüz algılama
İnsanların yer aldığı resimlerde yüzler genellikle resmin en önemli kısmıdır ve görüntü yakalanırken hem odağı 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>) parametrelerinin etkisi yoktur.
Kamera uygulamanızda yüz algılama özelliğini kullanmak için birkaç genel adımı uygulamanız gerekir:
- Cihazda yüz algılama özelliğinin desteklendiğinden emin olun.
- Yüz algılama dinleyicisi oluşturma
- Yüz algılama dinleyicisini kamera nesnenize ekleme
- Önizlemeden sonra (ve her önizleme yeniden başlatıldıktan sonra) yüz algılamayı başlatın.
Yüz algılama özelliği tüm cihazlarda desteklenmez. getMaxNumDetectedFaces() numarasını arayarak bu özelliğin desteklenip desteklenmediğini kontrol edebilirsiniz. Bu kontrolün bir örneği, aşağıdaki startFaceDetection() örnek yönteminde gösterilmiştir.
Yüz algılandığında bildirim almak ve yanıt vermek 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 dinleyici 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 ayarlarsınız:
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. Yüz algılamayı başlatmak için bir yöntem oluşturun. Böylece, aşağıdaki örnek kodda gösterildiği gibi gerektiğinde bu yöntemi çağırabilirsiniz.
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 (veya yeniden başlattığınızda) yüz algılamayı başlatmanız gerekir. Önizleme sınıfı oluşturma bölümünde gösterilen önizleme sınıfını kullanıyorsanız startFaceDetection() yönteminizi önizleme sınıfınızdaki hem surfaceCreated() hem de surfaceChanged() yöntemlerine ekleyin. Bu işlemi aşağıdaki örnek kodda gösterildiği gibi yapabilirsiniz.
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() yöntemini çağırdıktan sonra çağırmayı unutmayın. Kamera uygulamanızın ana etkinliğinin onCreate() yönteminde yüz algılamayı başlatmaya çalışmayın. Uygulamanızın yürütülmesinde bu noktada önizleme kullanılamaz.
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ı bir sekans için görüntüleri kaydetmek üzere MediaRecorder kullanır.
MediaRecorder ile zaman atlamalı video kaydetmek için kaydedici nesnesini normal bir video kaydediyormuş gibi yapılandırmanız, saniyedeki kare sayısını düşük bir sayıya ayarlamanız ve aşağıdaki kod örneğinde gösterildiği gibi zaman atlamalı 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 kapsamlı bir yapılandırma prosedürünün parçası olarak yapılmalıdır. Tam bir yapılandırma kodu örneği için MediaRecorder'ı yapılandırma başlıklı makaleyi inceleyin. Yapılandırma tamamlandıktan sonra, normal bir video klip kaydediyormuş gibi video kaydını başlatırsınız. MediaRecorder uygulamasını yapılandırma ve çalıştırma hakkında daha fazla bilgi için Video çekme başlıklı makaleyi inceleyin.
Camera2Video 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ın, getCameraCharacteristics() yönteminin döndürdüğü aşağıdaki alanların değerlerine erişebilmesi için CAMERA iznine sahip olması gerekir:
LENS_POSE_ROTATIONLENS_POSE_TRANSLATIONLENS_INTRINSIC_CALIBRATIONLENS_RADIAL_DISTORTIONLENS_POSE_REFERENCELENS_DISTORTIONLENS_INFO_HYPERFOCAL_DISTANCELENS_INFO_MINIMUM_FOCUS_DISTANCESENSOR_REFERENCE_ILLUMINANT1SENSOR_REFERENCE_ILLUMINANT2SENSOR_CALIBRATION_TRANSFORM1SENSOR_CALIBRATION_TRANSFORM2SENSOR_COLOR_TRANSFORM1SENSOR_COLOR_TRANSFORM2SENSOR_FORWARD_MATRIX1SENSOR_FORWARD_MATRIX2
Ek örnek kod
Örnek uygulamaları indirmek için Camera2Basic örneği ve Resmi CameraX örnek uygulaması sayfalarını inceleyin.