In dieser Lektion erfahren Sie, wie Sie die Kamera-Hardware direkt mit die Framework-APIs.
Hinweis:Diese Seite bezieht sich auf die Camera-Klasse, die eingestellt wurde. Wir empfehlen die Verwendung von CameraX oder, für bestimmte Anwendungsfälle, Camera2. Sowohl CameraX als auch Camera2 unterstützen Android 5.0 (API-Level 21) und höher.
Die direkte Steuerung einer Gerätekamera erfordert viel mehr Code als das Anfordern von Bildern oder Videos. aus vorhandenen Kamera-Apps. Wenn Sie jedoch eine spezielle Kamera-App oder etwas vollständig in Ihre App-UI integriert ist, erfahren Sie in dieser Lektion.
Weitere Informationen finden Sie in den folgenden verwandten Ressourcen:
Kameraobjekt öffnen
Das Abrufen einer Instanz des Camera
-Objekts ist der erste Schritt im
die Kamera direkt zu steuern. Wie bei der Kamera-App von Android ist das
empfohlene Methode für den Zugriff auf die Kamera besteht darin, Camera
in einem separaten Thread zu öffnen
die ab onCreate()
gestartet wurde. Dieser Ansatz ist eine gute Idee,
da dies eine Weile dauern und den UI-Thread beeinträchtigen kann. Bei einer einfacheren Implementierung
Das Öffnen der Kamera kann auf die onResume()
-Methode übertragen werden, um die Wiederverwendung von Code zu erleichtern und den Ablauf des
einfach steuern können.
Durch den Aufruf von Camera.open()
wird eine
Ausnahme, wenn die Kamera bereits von einer anderen Anwendung verwendet wird.
in einem try
-Block.
Kotlin
private fun safeCameraOpen(id: Int): Boolean { return try { releaseCameraAndPreview() mCamera = Camera.open(id) true } catch (e: Exception) { Log.e(getString(R.string.app_name), "failed to open Camera") e.printStackTrace() false } } private fun releaseCameraAndPreview() { preview?.setCamera(null) mCamera?.also { camera -> camera.release() mCamera = null } }
Java
private boolean safeCameraOpen(int id) { boolean qOpened = false; try { releaseCameraAndPreview(); camera = Camera.open(id); qOpened = (camera != null); } catch (Exception e) { Log.e(getString(R.string.app_name), "failed to open Camera"); e.printStackTrace(); } return qOpened; } private void releaseCameraAndPreview() { preview.setCamera(null); if (camera != null) { camera.release(); camera = null; } }
Seit API-Level 9 unterstützt das Kamera-Framework mehrere Kameras. Wenn Sie das
alten API verwenden und open()
ohne eine
erhalten Sie die erste Rückkamera.
Kameravorschau erstellen
Nutzer, die ein Bild aufnehmen, müssen normalerweise eine Vorschau des Motivs sehen, bevor sie darauf klicken.
den Auslöser. Dazu können Sie mit SurfaceView
eine Vorschau des
den Sensor der Kamera erkennt.
Vorschauklasse
Damit Sie eine Vorschau anzeigen können, benötigen Sie einen Vorschaukurs. Die
Für die Vorschau ist eine Implementierung der android.view.SurfaceHolder.Callback
-Schnittstelle erforderlich, die zum Übergeben von Bildern verwendet wird.
von der Kamerahardware an die Anwendung übertragen.
Kotlin
class Preview( context: Context, val surfaceView: SurfaceView = SurfaceView(context) ) : ViewGroup(context), SurfaceHolder.Callback { var mHolder: SurfaceHolder = surfaceView.holder.apply { addCallback(this@Preview) setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS) } ... }
Java
class Preview extends ViewGroup implements SurfaceHolder.Callback { SurfaceView surfaceView; SurfaceHolder holder; Preview(Context context) { super(context); surfaceView = new SurfaceView(context); addView(surfaceView); // Install a SurfaceHolder.Callback so we get notified when the // underlying surface is created and destroyed. holder = surfaceView.getHolder(); holder.addCallback(this); holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } ... }
Die Vorschauklasse muss vor dem Livestream an das Camera
-Objekt übergeben werden.
wie die Bildvorschau gestartet werden kann, wie im nächsten Abschnitt beschrieben.
Vorschau festlegen und starten
Eine Kamerainstanz und die zugehörige Vorschau müssen in einer bestimmten
wobei das Kameraobjekt an erster Stelle steht. Im Snippet unten enthält der
Prozess der Initialisierung der Kamera ist gekapselt, sodass Camera.startPreview()
vom
setCamera()
-Methode, wenn der Nutzer eine Änderung an der
Kamera. Die Vorschau muss auch in der Callback-Methode der Vorschauklasse surfaceChanged()
neu gestartet werden.
Kotlin
fun setCamera(camera: Camera?) { if (mCamera == camera) { return } stopPreviewAndFreeCamera() mCamera = camera mCamera?.apply { mSupportedPreviewSizes = parameters.supportedPreviewSizes requestLayout() try { setPreviewDisplay(holder) } catch (e: IOException) { e.printStackTrace() } // Important: Call startPreview() to start updating the preview // surface. Preview must be started before you can take a picture. startPreview() } }
Java
public void setCamera(Camera camera) { if (mCamera == camera) { return; } stopPreviewAndFreeCamera(); mCamera = camera; if (mCamera != null) { List<Size> localSizes = mCamera.getParameters().getSupportedPreviewSizes(); supportedPreviewSizes = localSizes; requestLayout(); try { mCamera.setPreviewDisplay(holder); } catch (IOException e) { e.printStackTrace(); } // Important: Call startPreview() to start updating the preview // surface. Preview must be started before you can take a picture. mCamera.startPreview(); } }
Kameraeinstellungen ändern
Über die Kameraeinstellungen wird die Art und Weise geändert, wie die Kamera Bilder aufnimmt – vom Zoom zur Belichtungskompensation. In diesem Beispiel wird nur die Größe der Vorschau geändert. finden Sie im Quellcode der Kamera-App.
Kotlin
override fun surfaceChanged(holder: SurfaceHolder, format: Int, w: Int, h: Int) { mCamera?.apply { // Now that the size is known, set up the camera parameters and begin // the preview. parameters?.also { params -> params.setPreviewSize(previewSize.width, previewSize.height) requestLayout() parameters = params } // Important: Call startPreview() to start updating the preview surface. // Preview must be started before you can take a picture. startPreview() } }
Java
@Override public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { // Now that the size is known, set up the camera parameters and begin // the preview. Camera.Parameters parameters = mCamera.getParameters(); parameters.setPreviewSize(previewSize.width, previewSize.height); requestLayout(); mCamera.setParameters(parameters); // Important: Call startPreview() to start updating the preview surface. // Preview must be started before you can take a picture. mCamera.startPreview(); }
Vorschauausrichtung festlegen
Die meisten Kamera-Apps fixieren das Display im Querformat, da dies die natürliche
Ausrichtung des Kamerasensors. Diese Einstellung hindert dich nicht daran, den Porträtmodus zu verwenden.
Fotos, da die Ausrichtung des Geräts im EXIF-Header aufgezeichnet wird. Mit der Methode setCameraDisplayOrientation()
können Sie
wie die Vorschau angezeigt wird, ohne die Aufzeichnung des Bildes zu beeinflussen. In Android vor früheren
API-Level 14 aktiviert haben, müssen Sie die Vorschau beenden, bevor Sie die Ausrichtung ändern, und sie dann neu starten.
Foto aufnehmen
Camera.takePicture()
verwenden
um ein Bild aufzunehmen, nachdem die Vorschau gestartet wurde. Sie können Camera.PictureCallback
- und Camera.ShutterCallback
-Objekte erstellen und an Camera.takePicture()
übergeben.
Wenn Sie fortlaufend Bilder erfassen möchten, können Sie eine Camera.PreviewCallback
erstellen, in der onPreviewFrame()
implementiert ist. Für
nur ausgewählte Vorschau-Frames aufnehmen oder eine
verzögerte Aktion zum Aufruf von takePicture()
.
Vorschau erneut starten
Nachdem ein Bild aufgenommen wurde, müssen Sie die Vorschau erneut starten, bevor der Nutzer ein weiteres Bild machen kann. In diesem Beispiel erfolgt der Neustart durch Überlastung auf den Auslöser.
Kotlin
fun onClick(v: View) { previewState = if (previewState == K_STATE_FROZEN) { camera?.startPreview() K_STATE_PREVIEW } else { camera?.takePicture(null, rawCallback, null) K_STATE_BUSY } shutterBtnConfig() }
Java
@Override public void onClick(View v) { switch(previewState) { case K_STATE_FROZEN: camera.startPreview(); previewState = K_STATE_PREVIEW; break; default: camera.takePicture( null, rawCallback, null); previewState = K_STATE_BUSY; } // switch shutterBtnConfig(); }
Vorschau beenden und Kamera wieder freigeben
Sobald Ihre Anwendung die Kamera nicht mehr benötigt, können Sie sie bereinigen. In
muss das Objekt Camera
freigegeben werden, da andernfalls die Gefahr besteht, dass andere
einschließlich neuer Instanzen Ihrer eigenen Anwendung.
Wann sollten Sie die Vorschau beenden und die Kamera wieder freigeben? Nun, wenn Sie Ihre
Vorschauoberfläche zerstört ist ein Hinweis darauf, dass es Zeit ist,
Sehen Sie sich eine Vorschau an und lassen Sie die Kamera wieder los, wie in diesen Methoden aus der Klasse Preview
gezeigt.
Kotlin
override fun surfaceDestroyed(holder: SurfaceHolder) { // Surface will be destroyed when we return, so stop the preview. // Call stopPreview() to stop updating the preview surface. mCamera?.stopPreview() } /** * When this function returns, mCamera will be null. */ private fun stopPreviewAndFreeCamera() { mCamera?.apply { // Call stopPreview() to stop updating the preview surface. stopPreview() // Important: Call release() to release the camera for use by other // applications. Applications should release the camera immediately // during onPause() and re-open() it during onResume()). release() mCamera = null } }
Java
@Override public void surfaceDestroyed(SurfaceHolder holder) { // Surface will be destroyed when we return, so stop the preview. if (mCamera != null) { // Call stopPreview() to stop updating the preview surface. mCamera.stopPreview(); } } /** * When this function returns, mCamera will be null. */ private void stopPreviewAndFreeCamera() { if (mCamera != null) { // Call stopPreview() to stop updating the preview surface. mCamera.stopPreview(); // Important: Call release() to release the camera for use by other // applications. Applications should release the camera immediately // during onPause() and re-open() it during onResume()). mCamera.release(); mCamera = null; } }
Zu Beginn der Lektion war dieser Vorgang auch Teil der setCamera()
-Methode. Die Initialisierung einer Kamera beginnt also immer mit dem Anhalten des
in der Vorschau ansehen.