Prévisualisation de la caméra traitement de données d'image avec Android L et la caméra 2 API
Je travaille sur une application android qui est le traitement de l'image d'entrée à partir de l'appareil photo et l'affiche à l'utilisateur. C'est assez simple, j'ai enregistrer un PreviewCallback
sur l'appareil photo de l'objet avec le setPreviewCallbackWithBuffer
.
C'est facile et fonctionne parfaitement avec le vieil appareil photo de l'API
public void onPreviewFrame(byte[] data, Camera cam) {
//custom image data processing
}
J'essaie de port mon application pour prendre avantage de la nouvelle Caméra 2 de l'API et je ne suis pas sûr exactement comment doit-je faire. J'ai suivi le Camera2Video dans L Aperçu des échantillons qui permet d'enregistrer une vidéo. Cependant, il n'y a pas d'image directe de transfert de données dans l'échantillon, donc je ne comprends pas exactement où je vais le chercher, le pixel de l'image des données et comment le traiter.
Quelqu'un pourrait-il m'aider ou de suggérer la manière dont on peut obtenir la fonctionnalité de PreviewCallback
dans android L, ou comment il est possible de traiter les données de l'aperçu de la caméra avant de l'afficher à l'écran? (il n'y a pas d'aperçu de rappel sur l'appareil photo de l'objet)
Merci!
- ont u triées ce problème.
- Oui, je l'ai fait. Vérifier VP de la réponse et aussi Camera2Basic et Camera2Video à partir d'android échantillons. Vous devez créer un ImageReader et l'utilisation
setOnImageAvailableListener
pour obtenir une nouvelle image lorsqu'ils sont capturés. Afin de dessiner une image que j'ai créé OpenGL surface, ce qui rend la texture et un shader qui convertitYUV_420_888
àRGB
. - Merci, j'ai vérifié à la fois repos et vice-président de la réponse. Lorsque j'ai mis addTarget(mImageReader.getSurface()); Il donne seulement trois cadres onImageAvailable après qu'il se fige à l'aperçu.
- Cette (ou quelque chose de similaire) peut se produire lorsque vous n'avez pas lu/fermer l'image de la ImageReader. Assurez-vous que l'auditeur
onImageAvailable(...)
vous faire lire et de fermer l'image. L'Auditeur ne peut pas être vide, même si vous n'utilisez pas l'image, vous devez la lire (par exemple avecreader.acquireNextImage()
). - Merci @bubo. Il m'a fallu un certain temps à comprendre ce comportement, car il n'était pas mentionné dans la documentation.
Vous devez vous connecter pour publier un commentaire.
Depuis le
Camera2
API est très différent de l'actuelCamera
de l'API, il peut être utile de passer par la documentation.Un bon point de départ est
camera2basic
exemple. Il montre comment utiliserCamera2
API et configurerImageReader
pour obtenir des images JPEG et d'enregistrerImageReader.OnImageAvailableListener
de recevoir ces imagesPour recevoir les images de prévisualisation, vous devez ajouter votre
ImageReader
surface desetRepeatingRequest
'sCaptureRequest.Builder
.Aussi, vous devez définir
ImageReader
's formatYUV_420_888
, qui vous donnera 30fps à 8 mpx (La documentation des garanties de 30fps à 8 mpx pour le Nexus 5).YUV_420_888
l'aperçu de l'appareil photo est nettement à la traîne (en comparaison avec Caméra1 dePreviewCallback
) et la production de plus de 10 FPS sur Moto G3 (tout en produisant plus de 30 FPS avec la même résolution sur la Caméra1). Est-ce un problème connu?Combinant quelques réponses en un plus digeste car @VP de la réponse, même si c'est clair, c'est difficile à comprendre si c'est votre première fois le déplacement de la Caméra à la Caméra 2:
À l'aide de https://github.com/googlesamples/android-Camera2Basic comme un point de départ, de modifier les éléments suivants:
Dans
createCameraPreviewSession()
init une nouvelleSurface
demImageReader
Ajouter que la nouvelle surface comme un objectif de production de votre
CaptureRequest.Builder
variable. À l'aide de la Camera2Basic de l'échantillon, la variable seramPreviewRequestBuilder
Voici l'extrait de code avec les nouvelles lignes (voir mon @AngeloS commentaires):
Prochain, dans
setUpCameraOutputs()
, changer le format deImageFormat.JPEG
àImageFormat.YUV_420_888
lorsque vous init votreImageReader
. (PS, je recommande également l'abandon de votre taille d'aperçu pour un fonctionnement plus doux - une fonctionnalité intéressante de la caméra 2)Enfin, dans votre
onImageAvailable()
méthode deImageReader.OnImageAvailableListener
, assurez-vous d'utiliser @Kamala la suggestion parce que l'aperçu s'arrête après quelques images, si vous ne fermez pas iljava.lang.IllegalArgumentException: submitRequestList:216: Request targets Surface that is not part of current capture session
, mais à l'aide de Google CameraView au lieu de Camera2Basic.onImageAvailable
fonction. Ceci, cependant, ne sera pas afficher l'image dans l'aperçu. Droit? Comment faire pour afficher l'image sur l'aperçu(TextureView
) après le traitement est terminé?Dans le ImageReader.OnImageAvailableListener classe, l'image après la lecture comme indiqué ci-dessous (cela permettra de libérer la mémoire tampon de capture suivante). Vous aurez à gérer une exception près
J'avais besoin de la même chose, j'ai donc utilisé leur exemple et ajouté un appel à une nouvelle fonction lorsque l'appareil est en état d'aperçu.
La
savePreviewShot()
est tout simplement une version recyclée de l'originalcaptureStillPicture()
adaptés pour utiliser le modèle d'aperçu.ImageReader
pour que. Lorsqu'une image est disponible, vous pouvez déclencher un thread séparé pour enregistrer le fichier, de sorte que votre thread principal n'est pas chargé avec elle. Vous pouvez trouver beaucoup d'exemples en ligne.Il est préférable d'init
ImageReader
avec max image de la mémoire tampon est2
ensuite utiliserreader.acquireLatestImage()
à l'intérieur deonImageAvailable()
.Parce que
acquireLatestImage()
permettra d'acquérir la dernière Image de la ImageReader de la file d'attente, à l'abandon ancienne. Cette fonction est recommandée pour une utilisation suracquireNextImage()
pour la plupart des cas d'utilisation, car il est plus adapté pour en temps réel de traitement. Notez que max image de la mémoire tampon doit être d'au moins2
.Et n'oubliez pas de
close()
votre image après traitement.