2010-01-12 6 views

Répondre

41

Vous avez probablement besoin d'une taille de prévisualisation non valide. Si vous vérifiez les résultats de adb logcat vous verrez probablement quelque chose comme ceci:

E/QualcommCameraHardware(22732): Invalid preview size requested: 480x724 

La solution est de demander le plus proche de la taille aperçu disponible à celui que vous souhaitez; vous pouvez obtenir une liste des tailles d'aperçu disponibles en appelant getSupportedPreviewSizes dans l'objet Camera.Parameters retourné par Camera.getParameters.

+0

Vous avez raison, sauf qu'il essayait de le mettre à 320x480 et 480x320 aurait travaillé. Cela m'amène à ma question suivante, pourquoi la méthode SurfaceHolder.Callback.surfaceChanged() a-t-elle été appelée avec une résolution aussi basse qui ne correspond même pas au format de l'appareil? –

+2

@Erik B - Je me rends compte que c'est en retard d'une réponse à ce commentaire, mais c'est probablement parce que votre application est en mode de compatibilité, et le système traite les pixels de votre application comme 0,66 fois la résolution réelle. Ainsi 480 x 800 sera présenté à votre application comme 320x533, en rasant probablement quelques pixels horizontalement ou verticalement pour la barre d'état, sauf si votre activité est en plein écran. –

+0

Que faites-vous avant la version 5 de l'API? (Disons que je veux être compatible avec Android 1.5) – uvgroovy

26

Je corrige cela en faisant ce que dit Roman, avec le code:

Camera.Parameters parameters = camera.getParameters(); 
    List<Camera.Size> sizes = parameters.getSupportedPreviewSizes(); 
    Camera.Size cs = sizes.get(0); 
    parameters.setPreviewSize(cs.width, cs.height); 
    camera.setParameters(parameters); 
10

Pour ce que ça vaut la peine, la source de ma question a fini par être que je tentais d'appeler parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); sans d'abord vérifier que les modes flash ont été pris en charge en vérifiant que parameters.getFlashMode() != null.

Il existe plusieurs causes pour cette exception mal documentée. Vérifiez donc tous vos paramètres et pas seulement que vous utilisez un supportedPreviewSize.

+0

Cela m'a aidé. :) merci pour le partage –

+1

if (! getBaseContext(). getPackageManager(). hasSystemFeature ( PackageManager.FEATURE_CAMERA_FLASH)) { // Le flash de l'appareil photo n'est pas disponible sur l'appareil } –

2

Aucun de ce qui précède n'a résolu cela pour moi. Ajout de ce code avant de définir les paramètres a quand même.

// stop preview before making changes 
    try { 
     mCamera.stopPreview(); 
    } catch (Exception e){ 
     // ignore: tried to stop a non-existent preview 
    } 

//now set your parameters 
0

Certains projet de caméra open source comme opencamera utilisez toujours try-catch appeler Camera.setParameters:

private void setCameraParameters(Camera.Parameters parameters) { 
    if(MyDebug.LOG) 
     Log.d(TAG, "setCameraParameters"); 
    try { 
     camera.setParameters(parameters); 
     if(MyDebug.LOG) 
      Log.d(TAG, "done"); 
    } catch (RuntimeException e) { 
     // just in case something has gone wrong 
     if(MyDebug.LOG) 
      Log.d(TAG, "failed to set parameters"); 
     e.printStackTrace(); 
     count_camera_parameters_exception++; 
    } 
} 

en outre, toujours la dernière getParameters avant d'appeler setParameters comme ceci:

void setRotation(int rotation) { 
    Camera.Parameters parameters = this.getParameters(); 
    parameters.setRotation(rotation); 
    setCameraParameters(parameters); 
} 
0

la solution de Sam est correcte mais l'image de sortie est encore zoomée un peu sur plusieurs tablettes. Une des meilleures pratiques que j'ai trouvées sur Internet, nous devrions définir dans l'hôte de caméra de sorte que les propriétés seront réutilisées chaque fois que la caméra est reprise. méthode ici est mis en œuvre CameraHost:

@Override 
     public Parameters adjustPreviewParameters(Parameters parameters) { 
      List<Camera.Size> sizes = parameters.getSupportedPreviewSizes(); 
      Camera.Size cs = sizes.get(0); 
      parameters.setPreviewSize(cs.width, cs.height); 
      return super.adjustPreviewParameters(parameters); 
     } 
2

Pour moi, cela se passerait-il après avoir pris une photo et l'aperçu gèlerait, jusqu'à ce que je mis à jour mon appel pour les paramètres à être les suivants. Il est toujours important avec cette erreur de s'assurer que vous vérifiez tous les paramètres que la caméra demande de régler pour vous assurer que tous les paramètres que vous demandez à la caméra de se régler sont possibles pour la caméra.

Camera.Parameters parameters = myCamera.getParameters(); 

Avec la taille de l'aperçu:

if (myCamera.getParameters().getSupportedPreviewSizes() != null){ 
    Camera.Size previewSize = getOptimalPreviewSize(myCamera.getParameters().getSupportedPreviewSizes(), width, height);; 
    parameters.setPreviewSize(previewSize.width, previewSize.height); 
} 

Avec les modes flash/mise au point:

if(parameters.getSupportedFocusModes() != null && parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)){ 
    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); 
} 

if (parameters.getSupportedFlashModes() != null && parameters.getSupportedFlashModes().contains(Camera.Parameters.FLASH_MODE_AUTO)){ 
    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO); 

} 

myCamera.setParameters(parameters); 

etc. Tout cela enveloppé dans un joli try {} catch() {} fonctionne très bien. Bonne chance.

Voici la taille de getOptimalPreview de this great tutorial:

private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int width, int height) 
    { 
     // Source: http://stackoverflow.com/questions/7942378/android-camera-will-not-work-startpreview-fails 
     Camera.Size optimalSize = null; 

     final double ASPECT_TOLERANCE = 0.1; 
     double targetRatio = (double) height/width; 

     // Try to find a size match which suits the whole screen minus the menu on the left. 
     for (Camera.Size size : sizes){ 

      if (size.height != width) continue; 
      double ratio = (double) size.width/size.height; 
      if (ratio <= targetRatio + ASPECT_TOLERANCE && ratio >= targetRatio - ASPECT_TOLERANCE){ 
       optimalSize = size; 
      } 
     } 

     // If we cannot find the one that matches the aspect ratio, ignore the requirement. 
     if (optimalSize == null) { 
      // TODO : Backup in case we don't get a size. 
     } 

     return optimalSize; 
    } 
Questions connexes