Android yapısı, cihazlarda bulunan çeşitli kameralar ve kamera özellikleri desteği sunarak uygulamalarınızda fotoğraf ve video çekmenize olanak tanır. Bu belgede, resim ve video yakalamaya yönelik hızlı ve basit bir yaklaşım açıklanmakta 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. KameraX 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 bakın:
Dikkat edilmesi gereken noktalar
Uygulamanızın, Android cihazlarda kameraları kullanmasını etkinleştirmeden önce, uygulamanızın bu donanım özelliğini nasıl kullanmak istediğiyle ilgili birkaç soru üzerine düşünmeniz gerekir.
- Kamera Gereksinimi: Kamera kullanımı, uygulamanızın kamerası olmayan bir cihaza yüklenmesini istemediğiniz kadar önemli mi? Bu durumda manifest belgenizde kamera şartını beyan etmeniz gerekir.
- Hızlı Resim veya Özelleştirilmiş Kamera - Uygulamanız kamerayı nasıl kullanacak? Sadece hızlı bir resim veya video klip çekmek mi istiyorsunuz, yoksa uygulamanız kameraları kullanmak için yeni bir yöntem mi sunacak? Hızlı bir fotoğraf veya klip elde etmek için Mevcut Kamera Uygulamalarını Kullanma seçeneğini değerlendirin. Ö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, uygulamanız ön plandayken veya bir ön plan hizmetinin parçası olarak kamerayı kullanmanız gerekir.
- Depolama: Uygulamanızın oluşturduğu resim veya videoların yalnızca uygulamanız tarafından görülebilmesi ya da Galeri veya diğer medya uygulamaları ve sosyal uygulamalar gibi diğer uygulamalar tarafından kullanılabilmesi için paylaşılması mı amaçlanıyor? Uygulamanız kaldırılmış olsa bile resim 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 göz atın.
Temel bilgiler
Android çerçevesi, android.hardware.camera2
API veya kamera Intent
aracılığıyla resim 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ı geliştirirken resim veya video çekmek için kullanılabilir.
Camera
- Bu sınıf, cihaz kameralarını kontrol etmek için desteği sonlandırılmış eski 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
- Doğrudan
Camera
nesnesini kullanmadan resim veya video yakalamak içinMediaStore.ACTION_IMAGE_CAPTURE
ya daMediaStore.ACTION_VIDEO_CAPTURE
türünde intent işlemi kullanılabilir.
Manifest beyanları
Kamera API'si ile uygulamanızda geliştirmeye başlamadan önce, manifest dosyanızda kamera donanımının ve diğer ilgili özelliklerin kullanımına izin vermek için 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 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 eklemeniz, Google Play'in uygulamanızın, kamera içermeyen veya belirttiğ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ışmak için kamera veya kamera özelliği kullanabiliyor ancak bu özelliği gerektirmiyorsa bunu manifest dosyasında
android:required
özelliğini ekleyipfalse
olarak ayarlayarak belirtmeniz gerekir:<uses-feature android:name="android.hardware.camera" android:required="false" />
- Depolama İzni - Uygulamanız, Android 10 (API düzeyi 29) veya önceki sürümleri hedefliyorsa ve manifest dosyasında aşağıdakileri belirtiyorsa görüntüleri 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, görüntüleri GPS konum bilgileriyle etiketliyorsa
ACCESS_FINE_LOCATION
iznini 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 gerektiğini unutmayın:<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ının konumunu alma hakkında daha fazla bilgi için Konum Stratejileri'ne bakın.
Mevcut kamera uygulamalarını kullanarak
Fazladan koda gerek kalmadan uygulamanızda resim veya video çekmenin hızlı bir yolu, mevcut bir Android kamera uygulamasını çağırmak için Intent
kullanmaktır.
Ayrıntılar, Taking Photos Simply (Basitçe Fotoğrafları Çekme) ve Recording Videos (Video Kaydetme) eğitimlerinde açıklanmaktadı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 çekme kodunuzu yazmanız, kullanıcılarınıza daha çekici bir deneyim sunabilir.
Not: Aşağıdaki kılavuz, desteği sonlandırılmış eski Camera
API'si için geçerlidir. Yeni veya gelişmiş kamera uygulamaları için daha yeni android.hardware.camera2
API önerilir.
Uygulamanız için özel kamera arayüzü oluşturmaya yönelik genel adımlar aşağıda açıklanmıştır:
- Kamerayı Algıla ve Eriş: Kameraların olup olmadığını kontrol etmek ve erişim isteğinde bulunmak için kod oluşturun.
- Önizleme Sınıfı Oluştur -
SurfaceView
kapsamını genişleten veSurfaceHolder
arayüzünü uygulayan bir kamera önizleme sınıfı oluşturun. Bu sınıfta kameradan canlı görüntülerin önizlemesi yapılır. - Önizleme Düzeni oluşturun - Kamera önizleme sınıfını oluşturduktan sonra istediğiniz önizlemeyi ve kullanıcı arayüzü denetimlerini içeren bir görünüm düzeni oluşturun.
- Yakalama için İşleyicileri Ayarlayın - Bir düğmeye basma gibi kullanıcı işlemlerine yanıt olarak görüntü veya video yakalamayı başlatmak için arayüz kontrollerinize ilişkin işleyicileri bağlayın.
- Dosyaları Yakala ve Kaydet - Resim veya video çekmek ve çıktıyı kaydetmek için kodu ayarlayın.
- Kamerayı bırakma: Kamerayı kullandıktan sonra, uygulamanızın diğer uygulamaların kullanması için uygun şekilde serbest bırakması gerekir.
Kamera donanımı, paylaşılan bir kaynaktır ve uygulamanızın bu cihazı kullanmak isteyebilecek diğer uygulamalarla çakışmaması için dikkatli bir şekilde yönetilmesi gerekir. 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 çekmenin nasıl yapılacağı ve uygulamanız bittiğinde kameranın nasıl serbest bırakılacağı açıklanmaktadır.
Dikkat: Uygulamanız kullanıldığında Camera.release()
öğesini çağırarak Camera
nesnesini serbest bırakmayı unutmayın. Uygulamanız kamerayı doğru şekilde serbest bırakmazsa kendi uygulamanız tarafından yapılanlar da dahil olmak üzere kameraya erişmeyi deneyeceğiniz sonraki tüm denemeler başarısız olur ve uygulamalarınızın ya da diğer uygulamalarınızın kapatılmasına neden olabilir.
Kamera donanımı algılanıyor
Uygulamanız özellikle manifest beyanı kullanan bir 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 cihazların birden fazla kamerası olabilir. Örneğin, fotoğrafçılık için arka kamera ve görüntülü görüşmeler için ön kamera. Android 2.3 (API Düzeyi 9) ve sonraki sürümler, Camera.getNumberOfCameras()
yöntemini kullanarak bir cihazda kullanılabilen kameraların sayısını kontrol etmenize olanak tanır.
Kameralara erişme
Uygulamanızın çalıştığı cihazda kamera bulunduğunu belirlediyseniz (kameraya erişme niyeti kullanmıyorsanız) Camera
örneği alarak erişim isteğinde bulunmanız gerekir.
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ılıyorsa veya yoksa 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ümleri çalıştıran cihazlarda belirli kameralara Camera.open(int)
üzerinden erişebilirsiniz. Yukarıdaki örnek kod, birden fazla kamerası olan bir cihazın ilk arka kamerasına erişir.
Kamera özellikleri kontrol ediliyor
Bir kameraya erişim elde ettikten sonra Camera.getParameters()
yöntemini kullanarak ve desteklenen özellikler için döndürülen Camera.Parameters
nesnesini kontrol ederek kameranın özellikleri hakkında daha fazla bilgi edinebilirsiniz. API Düzeyi 9 veya üstünü 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 resim 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österebilen bir SurfaceView
değeridir. Böylece kullanıcılar resim veya videoyu çerçeveleyip çekebilir.
Aşağıdaki örnek kod, View
düzenine dahil edilebilecek temel bir kamera önizleme sınıfının nasıl oluşturulacağını gösterir. Bu sınıf, görünümü oluşturmak ve kaldırmak için geri çağırma etkinliklerini yakalamak amacıyla SurfaceHolder.Callback
uygular. Bu etkinlikler, kamera önizleme girişini atamak için gereklidir.
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 kullanmanız gerekir.
setPreviewSize()
yönteminde rastgele değerler ayarlamayın.
Not:
Android 7.0 (API düzeyi 24) ve sonraki sürümlerde kullanıma sunulan
Çoklu Pencere özelliği sayesinde, 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 bir düzende geniş kamera önizlemesini veya sinemaskop düzeni kullanarak tam tersini sığdırmanız gerekebilir.
Düzene önizleme yerleştirme
Önceki bölümde gösterilen örnekteki gibi bir kamera önizleme sınıfı, fotoğraf veya video çekmeye yönelik diğer kullanıcı arayüzü denetimleriyle birlikte bir etkinliğin düzenine yerleştirilmelidir. Bu bölümde, önizleme için temel bir düzenin ve etkinliğin nasıl oluşturulacağı gösterilmektedir.
Aşağıdaki düzen kodu, bir 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 resimlerine ek resim bilgileri veya kontrollerin yerleştirilmesi 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 bir yatay (yatay) düzen belirtir. Aşağıdaki kod ise uygulamanın yönünü yatay yönde sabitler. Kamera önizlemesini oluşturmada kolaylık olması için aşağıdaki bilgileri manifest dosyanıza 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) başlayarak, önizleme görüntüsünün döndürmesini ayarlamak için setDisplayOrientation()
yöntemini kullanabilirsiniz. Kullanıcı telefonu yeniden yönlendirirken önizleme yönünü değiştirmek için önizleme sınıfınızın surfaceChanged()
yönteminde önizlemeyi Camera.stopPreview()
ile durdurun ve yönü değiştirin, ardından Camera.startPreview()
ile önizlemeyi tekrar başlatın.
Kamera görünümünüzle ilgili etkinlikte, ö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ırakması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 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 çekiliyor
Bir önizleme sınıfı ve bunun gösterileceği bir görünüm düzeni oluşturduğunuzda, uygulamanızla görüntü yakalamaya başlamak için hazırsınız demektir. Uygulama kodunuzda, kullanıcı arayüzü kontrollerinizin fotoğraf çekerek kullanıcı işlemine yanıt vermesi için işleyiciler ayarlamanız gerekir.
Bir resmi almak için Camera.takePicture()
yöntemini kullanın. Bu yöntemde kameradan veri alan üç parametre kullanılır.
Verileri JPEG biçiminde almak için, resim verilerini almak üzere bir Camera.PictureCallback
arayüzü uygulamanız ve bunu bir dosyaya yazmanı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 View.OnClickListener
düğmesinden 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 yer alan mPicture
üyesi, yukarıdaki örnek kodu ifade eder.
Dikkat: Uygulamanız kullanıldığında Camera.release()
öğesini çağırarak Camera
nesnesini serbest bırakmayı unutmayın. Kameranın serbest bırakılması hakkında bilgi için Kamerayı serbest bırakma başlıklı makaleye bakın.
Video yakalama
Android çerçevesi kullanılarak video yakalama için Camera
nesnesinin dikkatli bir şekilde yönetilmesi ve MediaRecorder
sınıfıyla koordinasyon sağlanması gerekir. Camera
ile video kaydederken MediaRecorder
uygulamasının, Camera.open()
ve Camera.release()
görüşmelerinin yanı sıra kamera donanımına da erişmesine izin 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 itibaren Camera.lock()
ve Camera.unlock()
çağrıları sizin için otomatik olarak yönetilir.
Cihaz kamerasıyla resim çekmenin aksine, video çekmek için belirli bir arama sırası gerekir. Uygulamanıza başarıyla hazırlanmak ve video çekmek için aşağıda açıklandığı gibi belirli bir yürütme sırasını takip etmeniz gerekir.
- Kamerayı Aç - Kamera nesnesinin bir örneğini almak için
Camera.open()
öğesini kullanın. - Bağlantı Önizleme -
Camera.setPreviewDisplay()
ile kameraya birSurfaceView
bağlayarak canlı kamera görüntüsü önizlemesi hazırlayın. - Önizlemeyi Başlat - Canlı kamera resimlerini göstermeye başlamak için
Camera.startPreview()
numaralı telefonu arayın. - Video Kaydını Başlatın: Başarılı bir video kaydı için aşağıdaki adımlar sırayla tamamlanmalıdır:
- Kameranın Kilidini Açın -
Camera.unlock()
numaralı telefonu arayarakMediaRecorder
tarafından kullanılmak üzere kameranın kilidini açın. - MediaRecorder'ı yapılandırın - Aşağıdaki
MediaRecorder
yöntemlerini bu sırayla çağırın. Daha fazla bilgi içinMediaRecorder
referans belgelerini inceleyin.setCamera()
- Video çekimi için kullanılacak kamerayı ayarlayın. Uygulamanızın mevcutCamera
örneğini kullanın.setAudioSource()
- Ses kaynağını ayarlayın,MediaRecorder.AudioSource.CAMCORDER
kullanın.setVideoSource()
- Video kaynağını ayarlayın,MediaRecorder.VideoSource.CAMERA
kullanın.- Video çıkış biçimini ve kodlamayı ayarlayın. Android 2.2 (API Düzeyi 8) ve sonraki sürümler için
MediaRecorder.setProfile
yö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ı belirtin veyaMediaRecorder.OutputFormat.MPEG_4
.setAudioEncoder()
- Ses kodlama türünü ayarlayın, varsayılan ayarı belirtin veyaMediaRecorder.AudioEncoder.AMR_NB
.setVideoEncoder()
- Video kodlama türünü ayarlayın, varsayılan ayarı belirtin veyaMediaRecorder.VideoEncoder.MPEG_4_SP
.
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üzen öğesini belirtin. Bağlantı Ö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 başarısız olur. - MediaRecorder'ı Hazırlama -
MediaRecorder.prepare()
yöntemini çağırarakMediaRecorder
dosyasını sağlanan yapılandırma ayarlarıyla hazırlayın. - MediaRecorder'ı başlat:
MediaRecorder.start()
numaralı telefonu arayarak video kaydetmeye başlayın.
- Kameranın Kilidini Açın -
- Video Kaydını Durdurma: Video kaydını başarıyla tamamlamak için sırayla aşağıdaki yöntemleri uygulayın:
- MediaRecorder'ı durdur -
MediaRecorder.stop()
numaralı telefonu arayarak video kaydını durdurun. - MediaRecorder'ı Sıfırla: İsteğe bağlı olarak,
MediaRecorder.reset()
yöntemini çağırarak yapılandırma ayarlarını kaydediciden kaldırın. - MediaRecorder'ı Yayın -
MediaRecorder.release()
öğesini çağırarakMediaRecorder
uygulamasını yayınlayın. - Kamerayı Kilitleyin - Sonraki
MediaRecorder
oturumlarınınCamera.lock()
numaralı telefonu arayarak kamerayı kullanabilmesi için kamerayı kilitleyin. Android 4.0 (API düzeyi 14) sürümünden itibaren,MediaRecorder.prepare()
çağrısı başarısız olmadığı sürece bu çağrı gerekli değildir.
- MediaRecorder'ı durdur -
- Önizlemeyi Durdurma - Etkinliğiniz kamerayı kullanarak bittikten sonra
Camera.stopPreview()
aracını kullanarak önizlemeyi durdurun. - Kamerayı Bırak -
Camera.release()
numaralı telefonu çağırarak diğer uygulamaların kullanabilmesi için kamerayı serbest bırakın.
Not: MediaRecorder
aracı, önce bir kamera önizlemesi oluşturmadan kullanılabilir ve bu işlemin ilk birkaç adımını atlayabilirsiniz. Ancak kullanıcılar genellikle kayda başlamadan önce önizleme görmeyi tercih ettiklerinden bu işleme burada değinmez.
İ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, kaydı başlatmak 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ırayla 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, MediaRecorder
sınıfının video kaydı için doğru şekilde nasıl yapılandırılacağını ve hazırlanacağını göstermektedir.
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, CamcorderProfile
kullanmak yerine çıkış biçimini ve kodlama biçimleri 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 kayıt parametrelerine varsayılan ayarlar verilir ancak bu ayarları uygulamanız için değiştirmek isteyebilirsiniz:
setVideoEncodingBitRate()
setVideoSize()
setVideoFrameRate()
setAudioEncodingBitRate()
setAudioChannels()
setAudioSamplingRate()
MediaRecorder'ı başlatma ve durdurma
MediaRecorder
sınıfını kullanarak video kaydını başlatır ve durdururken aşağıda listelenen belirli bir sırayı takip etmeniz gerekir.
Camera.unlock()
ile kameranın kilidini açınMediaRecorder
öğesini yukarıdaki kod örneğinde gösterildiği gibi yapılandırınMediaRecorder.start()
uygulamasını kullanarak kaydı başlat- Videoyu kaydet
MediaRecorder.stop()
uygulamasını kullanarak kaydı durdur- Medya kaydediciyi
MediaRecorder.release()
ile bırakın Camera.lock()
uygulamasını kullanarak kamerayı kilitleyin
Aşağıdaki örnek kod, kamera ve MediaRecorder
sınıfı kullanılarak video kaydını doğru şekilde başlatmak ve durdurmak için bir düğmenin nasıl bağlanacağını göstermektedir.
Not: Video kaydını tamamlarken kamerayı serbest 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öntemle kameranın kilitlenmesi, MediaRecorder
örneğinin yapılandırılması ve hazırlanması işlemleri yapılır.
Kamera serbest bırakma
Kameralar, bir cihazdaki uygulamalar tarafından paylaşılan kaynaklardır. Uygulamanız
kamerayı bir Camera
örneği aldıktan sonra kamerayı kullanabilir. Bu nedenle, kamera nesnesini
uygulamayı kullanmayı durdurduğunda ve uygulamanız duraklatıldığında (Activity.onPause()
) bırakmaya özellikle dikkat etmeniz gerekir.
Uygulamanız kamerayı doğru şekilde bırakamazsa sonraki tüm girişimler başarısız
olarak kendi uygulamanız tarafından yapılan uygulamalar da dahil olmak üzere diğer uygulamaların
çökmesine veya kilitlenmesine 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ı doğru bir şekilde serbest bırakmazsa, kendi uygulamanız tarafından yapılanlar da dahil olmak üzere kameraya erişmeye yönelik sonraki tüm girişimler başarısız olur ve uygulamalarınızın veya diğer uygulamalarınızı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. Medya dosyalarını bir cihaza kaydetmek için pek çok olası dizin konumu vardır, ancak geliştirici olarak düşünmeniz gereken yalnızca iki standart konum vardır:
Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_PICTURES
) - Bu yöntem, resimlerin ve videoların kaydedilmesi için standart, paylaşılan ve önerilen konumu döndürür. Bu dizin paylaşılır (herkese açık). Böylece diğer uygulamalar bu konuma kaydedilen dosyaları kolayca keşfedebilir, okuyabilir, değiştirebilir ve silebilir. Uygulamanız kullanıcı tarafından kaldırılırsa bu konuma kaydedilen medya dosyaları kaldırılmaz. Kullanıcıların mevcut resimlerine ve videolarına müdahale etmemek amacıyla, aşağıdaki kod örneğinde gösterildiği gibi, uygulamanızın medya dosyaları için bu dizinde bir alt dizin oluşturmanız gerekir. Bu yöntem, Android 2.2'de (API Düzeyi 8) kullanılabilmektedir. Ö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şkilendirilmiş resimleri 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 uygulanmaz ve diğer uygulamalar bu dosyaları okuyabilir, değiştirebilir ve silebilir.
Aşağıdaki örnek kod, Intent
ile bir cihazın kamerasını çağırırken veya bir Kamera Uygulaması Oluşturma'nın parçası olarak kullanılabilecek bir medya dosyası için File
veya Uri
konumunun nasıl oluşturulacağını gösterir.
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()
politikasını kullanın. Daha fazla bilgi için Paylaşılan Dosyaları Kaydetme konusuna bakın.
URI'nın iş profillerini desteklemesi için önce
dosya URI'sini bir içerik URI'sine dönüştürün. Ardından, içerik URI'sini bir Intent
öğesinin EXTRA_OUTPUT
öğesine ekleyin.
Android cihaza dosya kaydetme hakkında daha fazla bilgi edinmek için Veri Depolama başlıklı makaleyi inceleyin.
Kamera özellikleri
Android, kamera uygulamanızla kontrol edebileceğiniz resim biçimi, flaş modu, odak ayarları ve daha pek çok kamera özelliğini destekler. 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 özellik ayarlanabilir. Ancak Camera.Parameters
uygulamasında 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 nesnesiyle kontrol edilen özelliklerin nasıl kullanılacağı hakkında daha ayrıntılı bilgi için aşağıdaki özellik listesinde bulunan API referans belgelerinin bağlantılarını izleyin.
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 | Bir resimdeki insan yüzlerini tanımlayabilir ve bu yüzleri odaklama, ölçüm ve beyaz dengesi için kullanabilirsiniz. |
Sayaç Alanları | 14 | Beyaz dengesini hesaplamak için bir resim içinde bir veya daha fazla alan belirtin |
Odaklanılan Alanlar | 14 | Odaklanmak için resimdeki 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 (kareyi yakalama) |
Zaman Atlama Videosu | 11 | Zaman atlamalı video kaydetmek için kareleri ayarlanmış gecikmelerle kaydedin |
Multiple Cameras |
9 | Ön ve arka kameralar dahil olmak üzere bir cihazda birden fazla kamera desteği |
Focus Distance |
9 | Kamera ile odaktaymış gibi görünen nesneler arasındaki mesafeleri bildirir |
Zoom |
8 | Resim büyütmeyi ayarlayın |
Exposure
Compensation |
8 | Işık pozlama seviyesini artır veya azalt |
GPS Data |
5 | Görsele coğrafi konum verilerini ekleyin veya dahil etmeyin |
White Balance |
5 | Çekilen görüntüdeki renk değerlerini etkileyen beyaz dengesi modunu ayarlayın |
Focus Mode |
5 | Kameranın otomatik, sabit, makro veya sonsuzluk gibi bir özneye nasıl odaklanacağını ayarlayın |
Scene Mode |
5 | Gece, plaj, kar veya mum ışığı sahneleri gibi belirli fotoğraf türleri için önceden ayarlanmış modu uygulayın. |
JPEG Quality |
5 | JPEG resmi için sıkıştırma düzeyini ayarlayın. Bu işlem, resim çıkış dosyası kalitesini ve boyutunu artırır veya azaltır |
Flash Mode |
5 | Flaşı açma, kapatma veya otomatik ayarı kullanma |
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 etme hakkında bilgi edinmek için Özellik kullanılabilirliğini kontrol etme bölümüne bakın.
Özelliklerin kullanılabilirliği kontrol ediliyor
Android cihazlarda kamera özelliklerini kullanmak için ilk önce anlamanız gereken ilk şey, 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 düzeyde desteklemek istediğinize karar vermektir. Bu kararı verdikten sonra, cihaz donanımının bu özellikleri destekleyip desteklemediğini ve bir özellik kullanılamadığında sorunsuz bir şekilde başarısız olduğunu kontrol eden kodu kamera uygulamanıza eklemeyi planlamalısınız.
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 ölçüde) 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 uygulama manifestinize ekleme yaparak bu özellikleri 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 ö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 aşağıdaki örnek kodda gösterildiği gibi 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 özellikleri için geçerlidir 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 ise, kamera donanımı yeni talimatları işleyip ardından güncellenmiş görüntü verilerini gönderdiğinden, parametre değişikliklerinin geçerli olması birkaç kare sürebilir.
Önemli: Bazı kamera özellikleri istediğiniz zaman 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 itibaren, önizleme yeniden başlatılmadan önizleme yönü değiştirilebilir.
Aşağıdakiler gibi diğer kamera özelliklerinin uygulanması için daha fazla kod gerekir:
- Ölçme ve odak alanları
- Yüz algılama
- Zaman atlamalı video
Aşağıdaki bölümlerde, bu özelliklerin nasıl uygulanacağına ilişkin kısa bir özet sunulmaktadır.
Ölçme ve odak alanları
Bazı fotoğrafik senaryolarda otomatik odaklanma ve ışık sayacı istenen sonuçları vermeyebilir. Kamera uygulamanız, Android 4.0 (API Düzeyi 14) sürümünden itibaren, uygulamanızın veya kullanıcıların görüntüde, odak veya ışık düzeyi ayarlarını belirlemek üzere kullanılacak alanları belirtmesine ve bu değerleri görüntü ya da video çekmek için kamera donanımına aktarmasına olanak tanıyan ek kontroller sağlayabilir.
Ölçme ve odaklama alanları, diğer kamera özelliklerine çok benzer. Bu alanları, Camera.Parameters
nesnesindeki yöntemlerle kontrol edersiniz. Aşağıdaki kod, Camera
örneği için iki ışık ölçme 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ındaki bir alanı belirtmek için kullanılan Rect
nesnesi ve kameraya bu alanın ışık ölçümü veya odak hesaplamalarında ne kadar önem verilmesi gerektiğini belirten bir ağırlık değeri.
Bir Camera.Area
nesnesindeki Rect
alanı, 2.000 x 2.000'lik bir birim ızgarası üzerinde eşlenen dikdörtgen bir şekil tanımlar. -1000, -1000 koordinatları, kamera görüntüsünün üst ve sol köşesini temsil eder. 1000, 1000 koordinatları ise aşağıdaki resimde gösterildiği gibi kamera görüntüsünün sağ alt köşesini temsil eder.
Şekil 1. Kırmızı çizgiler, kamera önizlemesinde bir Camera.Area
belirtmek için kullanılan 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 resmin dış kenarına karşılık gelir ve yakınlaştırma düzeyiyle daraltılmaz veya genişlemez. Benzer şekilde, Camera.setDisplayOrientation()
kullanılarak görüntü önizlemesinin döndürülmesi koordinat sistemini yeniden eşlemez.
Yüz algılama
İnsan içeren resimlerde, yüzler genellikle resmin en önemli parçasıdır ve resim ç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>)
'un herhangi bir 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şturun
- Yüz algılama dinleyiciyi kameranızdaki nesneye ekleyin
- Önizlemeden sonra (ve her önizleme yeniden başlatıldıktan sonra) yüz algılamayı 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österilmiştir.
Bir yüz algılandığında bildirim almak ve buna yanıt vermek için kamera uygulamanızın yüz algılama etkinliklerine yönelik 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 ayarlarsınız:
Kotlin
camera?.setFaceDetectionListener(MyFaceDetectionListener())
Java
camera.setFaceDetectionListener(new MyFaceDetectionListener());
Kamera önizlemesini her başlattığınızda (veya yeniden başlattığınızda) uygulamanız 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. Böylece, gerektiği gibi ç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 yüz algılamayı başlatmanız (veya yeniden 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 aşağıdaki örnek kodda gösterildiği gibi ö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: startPreview()
yöntemini çağırdıktan sonra bu yöntemi çağırmayı unutmayın. Önizleme, uygulamanızın yürütülürken bu noktada kullanılamaz. Bu nedenle, kamera uygulamanızın ana
etkinliğinin onCreate()
yönteminde yüz algılamayı başlatmayı denemeyin.
Zaman atlamalı video
Zaman atlamalı video, kullanıcıların birkaç saniye veya birkaç dakika arayla çekilen resimleri birleştiren video klipler oluşturmasına olanak tanır. Bu özellik, zaman atlamalı bir adım dizisi için görüntü kaydetmek amacıyla MediaRecorder
kullanır.
MediaRecorder
özelliğini kullanarak zaman atlamalı video kaydetmek için kaydedici nesnesini normal bir video kaydediyormuş gibi yapılandırmanız, 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 kalitesi 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 büyük bir yapılandırma prosedürü kapsamında yapılmalıdır. Tam yapılandırma kodu örneği için MediaRecorder'ı Yapılandırma bölümüne bakın. Yapılandırma tamamlandıktan sonra video kaydını, normal bir video klip kaydeder 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ı ş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şmek 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 göz atın.