58 votes

Android Appareil photo sans l'Aperçu

Je suis en train d'écrire un android 1.5 application qui commence juste après le démarrage.
C'est un service et doit prendre une photo sans aperçu. Cette application va enregistrer la lumière de la densité dans quelques domaines que ce soit. J'ai réussi à prendre une photo, mais la photo était en noir.

Après googler comme un fou, je suis tombé sur un bug thread à ce sujet. Si vous n'avez pas de générer un aperçu, l'image sera en noir depuis android appareil a besoin d'aperçu pour l'installation de l'exposition et de la concentration. J'ai créé une surfaceview et l'auditeur, mais le onSurfaceCreated événement n'est jamais déclenché.

Je suppose que la raison en est, la surface n'est pas visuellement. J'ai aussi vu quelques exemples de l'appel de la caméra de manière statique avec MediaStore.CAPTURE_OR_SOMETHING qui prend une image et l'enregistre dans le dossier de votre choix avec deux lignes de code mais il ne faut pas trop en photo.

Ai-je besoin de l'utilisation de la cib et bindservice pour appeler cette fonction, ou avez-vous une suggestion pour atteindre mon objectif (en prenant une photo sans l'aperçu) et si oui, voulez-vous me donner un petit morceau de code comme exemple?

52voto

il est vraiment étrange que la caméra sur la plate-forme android peut pas diffuser de la vidéo jusqu'à ce qu'il donné valide aperçu de surface. il semble que les architectes de la plate-forme a été de ne pas penser à la 3ème partie des applications de streaming vidéo à tous. même pour la réalité augmentée cas, l'image peut être présenté comme une sorte de visual substitution, non pas en temps réel du flux d'une caméra.

de toute façon, vous pouvez simplement redimensionner aperçu de la surface de 1x1 pixels et la mettre quelque part dans le coin de la widget (élément visuel). s'il vous plaît prêter attention - redimensionner aperçu de surface, pas d'image de la caméra de la taille.

bien sûr, un tel truc n'est pas à éliminer les flux de données (pour l'aperçu) qui consomme des ressources système et de la batterie.

39voto

J'ai trouvé la réponse à cette question dans l' Appareil photo Android Docs.

Remarque: Il est possible d'utiliser MediaRecorder sans la création d'un appareil photo aperçu du premier et passez les premières étapes de ce processus. Cependant, étant donné que les utilisateurs préfèrent généralement de voir un aperçu avant de commencer un l'enregistrement, ce processus n'est pas abordé ici.

Vous pouvez trouver des instructions étape par étape sur le lien ci-dessous. Après les instructions, il fera état de la citation que j'ai fournis ci-dessus.

http://developer.android.com/guide/topics/media/camera.html#capture-video

Mise à jour: Uhg, je suis ENCORE en train de perdre les points de réputation sur ce point. COMMENT PUIS-JE SUPPRIMER CE POST? Si vous RTFM, ÇA FONCTIONNE! Je vous le jure. Il travaille pour la vidéo. Il fonctionne pour les photos. J'ai posté parce que j'ai trouvé et ça fonctionne. Maintenant, un an plus tard, je suis encore en bas-voté. J'ai essayé le lien "supprimer" et il me demande si je veux "vote pour supprimer" ce post. Merci de ne pas voter de moi plus. Au lieu de cela, merci de répondre ici et me dire comment supprimer cette chose.

37voto

Frank Points 767

En fait c'est possible, mais vous devez faire semblant de le prévisualiser avec un mannequin SurfaceView

SurfaceView view = new SurfaceView(this);
c.setPreviewDisplay(view.getHolder());
c.startPreview();
c.takePicture(shutterCallback, rawPictureCallback, jpegPictureCallback);

Plus de détails trouvé dans mon blog.

Mise à jour 9/21/11: Apparemment, cela ne fonctionne pas pour tous les appareils Android.

22voto

Varun Gulshan Points 199

Sur Android 4.0 et au-dessus de l'API (niveau >= 14), vous pouvez utiliser TextureView pour prévisualiser le flux d'une caméra et de le rendre invisible afin de ne pas le montrer à l'utilisateur. Voici comment:

D'abord créer une classe pour mettre en œuvre un SurfaceTextureListener qui obtiendra le créer/mettre à jour des rappels pour la preview de la surface. Cette classe prend également un appareil photo de l'objet en tant qu'entrée, de sorte qu'il peut appeler la caméra startPreview fonction dès que la surface est créée:

public class CamPreview extends TextureView implements SurfaceTextureListener {

  private Camera mCamera;

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

  @Override
  public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
    Camera.Size previewSize = mCamera.getParameters().getPreviewSize();
    setLayoutParams(new FrameLayout.LayoutParams(
        previewSize.width, previewSize.height, Gravity.CENTER));

    try{
      mCamera.setPreviewTexture(surface);
     } catch (IOException t) {}

    mCamera.startPreview();
    this.setVisibility(INVISIBLE); // Make the surface invisible as soon as it is created
  }

  @Override
  public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
      // Put code here to handle texture size change if you want to
  }

  @Override
  public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
    return true;
  }

  @Override
  public void onSurfaceTextureUpdated(SurfaceTexture surface) {
      // Update your view here!
  }
}

Vous aurez également besoin de mettre en œuvre une classe de rappel pour traiter les données d'aperçu:

public class CamCallback implements Camera.PreviewCallback{
  public void onPreviewFrame(byte[] data, Camera camera){
     // Process the camera data here
  }
}

Le CamPreview et CamCallback classes d'installation de la caméra dans votre activité est onCreate() ou similaire fonction de démarrage:

// Setup the camera and the preview object
Camera mCamera = Camera.open(0);
CamPreview camPreview = new CamPreview(Context,mCamera);
camPreview.setSurfaceTextureListener(camPreview);

// Connect the preview object to a FrameLayout in your UI
// You'll have to create a FrameLayout object in your UI to place this preview in
FrameLayout preview = (FrameLayout) findViewById(R.id.cameraView); 
preview.addView(camPreview);

// Attach a callback for preview
CamCallback camCallback = new CamCallback();
mCamera.setPreviewCallback(camCallback);

20voto

Vlad Points 355

Il y a un moyen de le faire, mais c'est un peu délicat. ce qui doit être fait, c'est joindre une surfaceholder à la fenêtre du gestionnaire de service

WindowManager wm = (WindowManager) mCtx.getSystemService(Context.WINDOW_SERVICE);
params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
            WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
            PixelFormat.TRANSLUCENT);        
wm.addView(surfaceview, params);

et puis définissez

surfaceview.setZOrderOnTop(true);
mHolder.setFormat(PixelFormat.TRANSPARENT);

où mHolder est le support que vous obtenez à partir de la surface d'affichage.

de cette façon, vous pouvez jouer avec les surfaceview alpha, le rendre totalement transparent, mais la caméra sera toujours obtenir des images.

c'est comment je le fais. espérons que cela aide :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X