web-dev-qa-db-fra.com

Android - L'aperçu de l'appareil photo est latéral

J'utilise un aperçu pour afficher ce que la caméra voit à l'écran.

Je peux tout faire fonctionner correctement, créer une surface, définir une surface et la surface est affichée.

Cependant, il affiche toujours la photo à un angle de 90 degrés incorrect en mode portrait.

Comme dans l'image:

alt text

Je suis conscient que l'utilisation du code suivant va redresser l'image:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

Cependant, j'ai une prévisualisation dans une activité qui contient d'autres éléments et il n'est pas logique que mon activité soit affichée en mode paysage. (Son désactivé par défaut)

Je me demandais donc s'il était possible de changer l'orientation de l'aperçu. Et laisser le reste de mon activité correctement affiché en mode Portrait?

Ou de toute façon pour faire pivoter l'aperçu afin qu'il soit affiché correctement?

122
Donal Rafferty

Ce problème semblait être un bogue avec certains matériels voir ici mais peut être surmonté en utilisant l'appel à mCamera.setDisplayOrientation (degrés) disponible dans l'API 8. Voici comment je l'implémente:

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {            
    if (isPreviewRunning) {
        mCamera.stopPreview();
    }

    Parameters parameters = mCamera.getParameters();
    Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();

    if(display.getRotation() == Surface.ROTATION_0) {
        parameters.setPreviewSize(height, width);                           
        mCamera.setDisplayOrientation(90);
    }

    if(display.getRotation() == Surface.ROTATION_90) {
        parameters.setPreviewSize(width, height);                           
    }

    if(display.getRotation() == Surface.ROTATION_180) {
        parameters.setPreviewSize(height, width);               
    }

    if(display.getRotation() == Surface.ROTATION_270) {
        parameters.setPreviewSize(width, height);
        mCamera.setDisplayOrientation(180);
    }

    mCamera.setParameters(parameters);
    previewCamera();                      
}

And the previewCamera method :

public void previewCamera() {        
    try {           
        mCamera.setPreviewDisplay(mSurfaceHolder);          
        mCamera.startPreview();
        isPreviewRunning = true;
    } catch(Exception e) {
        Log.d(APP_CLASS, "Cannot start preview", e);    
    }
}

C’était sur un HTC Desire et je devais d’abord inscrire des instructions de consignation dans chacune des vérifications de rotation pour indiquer la rotation, puis déboguer sur l’appareil et regarder la sortie logCat pendant la rotation de l’appareil. Pour le HTC Desire, le téléphone était à 0 comme prévu (portrait), à 90 degrés, il faisait pivoter le téléphone à 90 degrés dans le sens inverse des aiguilles d'une montre (j'avais supposé que cela aurait été le sens des aiguilles d'une montre). Dans le code, vous verrez que je n'avais pas besoin de faire de rotation d'affichage lorsque le téléphone était à 90 ou 180 degrés - l'appareil semblait gérer cela lui-même. Un seul point ne fonctionne pas correctement: la rotation de 270 degrés correspond à une rotation de 90 degrés dans le sens des aiguilles d'une montre et les compteurs de rotation de l'écran sont corrects, mais si vous faites pivoter le dispositif à 270 degrés dans le sens inverse des aiguilles d'une montre, cela ne semble pas compenser correctement.

P.S. Notez le permutation de largeur et de hauteur dans les rotations appropriées.

144
John J Smith

essayez de définir l'orientation de l'affichage. Cela résout mon problème.

 mCamera.setDisplayOrientation(90);
16
ksu
 public void surfaceCreated(SurfaceHolder holder) {
     mCamera = Camera.open();
     mCamera.setDisplayOrientation(90);
     try {
         mCamera.setPreviewDisplay(holder);
         mCamera.setPreviewCallback(new PreviewCallback() {

             @Override
             public void onPreviewFrame(byte[] data, Camera camera) {
             }
         });

     } catch (Exception e) {
         e.printStackTrace();
     }
}

essayez ce code

13
jitendra G2

J'avais un problème avec la caméra frontale (problème à l'envers). Ensuite, j'ai utilisé la méthode suivante décrite dans Android Docs -

public void setCameraDisplayOrientation(Activity activity , int icameraId , Camera camera1s)
    {
        CameraInfo cameraInfo = new CameraInfo();

        Camera.getCameraInfo(icameraId, cameraInfo);

        int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();

        int degrees = 0; // k

        switch (rotation)
        {
        case Surface.ROTATION_0:
            degrees = 0;
            break;
        case Surface.ROTATION_90:
            degrees = 90;
            break;
        case Surface.ROTATION_180:
            degrees = 180;
            break;
        case Surface.ROTATION_270:
            degrees = 270;
            break;

        }

        int result;

        if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT)
        {
            // cameraType=CAMERATYPE.FRONT;

            result = (cameraInfo.orientation + degrees) % 360;
            result = (360 - result) % 360; // compensate the mirror

        }
        else
        { // back-facing

            result = (cameraInfo.orientation - degrees + 360) % 360;

        }
        // displayRotate=result;
        camera.setDisplayOrientation(result);


    }
4
Xar E Ahmer

Je l'ai fait en prenant conseil sur mCamera.setDisplayOrientation (90); mais aussi tourné le bitmap parce que pour une raison quelconque, les autres approches ne fonctionnent pas pour moi dans la version 2.3.3.

Pour faire pivoter le bitmap, j'ai fait ceci:

Matrix matrix = new Matrix();
matrix.postRotate(90);
imageView1 = new ImageView(this);
Bitmap bitmap = BitmapFactory.decodeFile(files[i].getAbsolutePath());
Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap , 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(rotatedBitmap, 80, 80, true);
imageView1.setImageBitmap(scaledBitmap);
3
yngrdyn
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;
    }

    try {
        mCamera.stopPreview();
    } catch (Exception e) {
        e.printStackTrace();
    }

    Camera.Parameters parameters = mCamera.getParameters();
    Display display = ((WindowManager) getContext().getSystemService(WINDOW_SERVICE)).getDefaultDisplay();

    if (display.getRotation() == Surface.ROTATION_0) {
        parameters.setPreviewSize(h, w);
        mCamera.setDisplayOrientation(90);
    }

    if (display.getRotation() == Surface.ROTATION_90) {
        parameters.setPreviewSize(w, h);
        mCamera.setDisplayOrientation(0);
    }

    if (display.getRotation() == Surface.ROTATION_180) {
        parameters.setPreviewSize(h, w);
        mCamera.setDisplayOrientation(270);
    }

    if (display.getRotation() == Surface.ROTATION_270) {
        parameters.setPreviewSize(w, h);
        mCamera.setDisplayOrientation(180);
    }

    previewCamera();
}

public void previewCamera() {
    try {
        mCamera.setPreviewDisplay(mHolder);
        mCamera.startPreview();
    } catch (Exception e) {
        //Log.d(APP_CLASS, "Cannot start preview", e);
        e.printStackTrace();
    }
}
0
sofi37

J'ai comparé mon code à celui du tutoriel et ce qui a finalement été résolu, c'est de mettre le code suivant dans mon AndroidManifext.xml: Dans le <activity> tag:

Android:screenOrientation="landscape"
Android:configChanges="keyboardHidden|orientation">
0
sbaechler