Estoy usando una vista previa para mostrar lo que la cámara ve en la pantalla.

Puedo conseguir que todo funcione bien, superficie creada, superficie y la superficie se muestra.

Sin embargo siempre se muestra la imagen en una incorrecta ángulo de 90 grados en el modo de retrato.

Tal como en la imagen:

Android - vista previa de la Cámara de costado

Soy consciente de que, utilizando el código siguiente se establece la imagen de la recta:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

Sin embargo, tengo la vista previa dentro de una Actividad que tiene otros elementos en ella y no tiene sentido para mi Actividad se muestra en el modo de paisaje. (Su deshabilitado por defecto)

Así que me preguntaba ¿hay algún modo de cambiar la orientación de la vista previa? Y dejar el resto de mi Actividad se muestran correctamente en el modo de Retrato?

O de todos modos para girar la vista previa para que se muestre correctamente?

7 Comentarios

  1. 142

    Este problema apareció al principio como un bug con cierto hardware ver aquí pero se puede superar mediante el uso de la llamada a mCamera.setDisplayOrientation(grados) disponibles en la API de 8. Así que esto es ¿cómo puedo implementar esto:

    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);    
        }
    }

    Esto fue en un HTC Desire y he tenido que inicialmente, en el registro de instrucciones en cada uno de la rotación de los cheques a decir lo que la rotación era y, a continuación, depurando en el dispositivo y visto el logCat de salida, mientras que girar el dispositivo. Para el HTC Desire, 0 fue el teléfono como se esperaba (retrato), 90 grados a girar el teléfono 90 grados en sentido antihorario (yo había asumido que hubiera sido de las agujas del reloj). En el código verás que no tenía necesidad de hacer cualquier rotación de la pantalla cuando el teléfono estaba en 90 o 180 grados – el dispositivo parecía manejar esto por sí mismo. Sólo un punto en el que no funciona correctamente: La rotación de 270 grados es cuando se gire el dispositivo de 90 grados a la derecha y la rotación de pantalla de contadores que aceptar pero si se rota el dispositivo de 270 grados en sentido antihorario, no parece compensar adecuadamente.

    P. S. Nota la swapover de la anchura y la altura en las correspondientes rotaciones.

    • pero setDisplayOrientation(grado); método admite formulario 2.2, ¿qué versión inferior?? los parámetros.métodos setrotation(90); parámetros.set(«orientación», «retrato»); no están funcionando. Si usted tiene alguna solución para versiones inferiores por favor me ayude.
    • He implementado una vista previa en mi app, que siempre se muestran en el modo de retrato. Yo siempre fui de la rotación de la pantalla 90 grados y esto parecía funcionar en todos los dispositivos hasta que la hemos probado en el HTC Desire C. Como yo que no cuente con el dispositivo para probar esto, me gustaría aclarar si esta revisión sugieren que finalmente se trabajó bien en el HTC desire. Gracias!
    • Sí, esto funcionó bien en el HTC Desire, en mi caso.
    • El mCamera.setParameters(parameters); declaración de accidente de mi aplicación, debido a que la superficie de las dimensiones no son válidos tamaño de la vista previa de mi teléfono (tal vez porque guardo la barra de estado visible?). Sin embargo, he encontrado que el uso mCamera.setDisplayOrientation(90) luego mCamera.setPreviewDisplay(mSurfaceHolder); sin el ajuste de los parámetros trabajado demasiado!
    • Si el dispositivo Auto Rotation is disabled, onSurfaceChanged no se llama, no importa la forma en que se gire. Así que, sin el trabajo de todo para que?
    • Gracias por los esfuerzos que trabajó para todos excepto los de Samsung Galaxy ACE con Android 2.3.6 versión. El método de setDisplayOrientation(90) no está funcionando.
    • mejor respuesta. Gracias Juan.
    • Hola, me han implementado la solución anterior, pero aún así visualización de la imagen en el paisaje. Yo lo he probado con el samsung galaxy s3.
    • Gracias man… me has salvado la vida… +1
    • sería más limpio, con una instrucción switch
    • No esta suponer que la vista previa es de lado a lado en TODOS los dispositivos? por su lado en algunos dispositivos y derecho en los demás…. hay una manera de comprobar si los dispositivos de la cámara por defecto de orientación en línea con el retrato lado del teléfono, o no?
    • cuando yo cambiar la anchura y la altura como en el código se extiende mi vista previa, pero cuando no funciona. me salvó un día!
    • Hola si establece la orientación en -> 90 y como la lógica de su altura y la anchura se intercambian por lo que no permiten establecer los parámetros como el tamaño no será compatible si intenta con 640X480

  2. 16

    intenta establecer la orientación de la pantalla. Se soluciona mi problema.

     mCamera.setDisplayOrientation(90);
    • en el momento de guardar se guarda la imagen de retrato en el paisaje.Alguna solución?
    • este indicador sólo se aplica a la pantalla de vista preliminar. No cambiar la orientación de la búfer devuelto en onPreviewFrame() o onPictureTaken()
  3. 13
     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();
         }
    }

    prueba este código

    • agradable gracias tio
    • en el momento de guardar se guarda la imagen de retrato en el paisaje.Alguna solución?
    • eso es probablemente que ver con la información EXIF de los parámetros.
  4. 4

    Yo estaba teniendo un problema con la Cámara frontal(al Revés de la revista). Luego he utilizado el siguiente método documentado en Android De Google 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);
    
    
        }
    • Este método proviene de la documentación de la cámara: developer.android.com/reference/android/hardware/…
    • Nada mal si después de documento oficial?
    • En particular, no, yo sólo quería dar crédito a la fuente y el punto de la gente de allí por más de un contexto. 🙂
  5. 3

    Yo lo hice siguiendo las recomendaciones de mCamera.setDisplayOrientation(90); pero también girar el mapa de bits ya que por alguna razón los otros enfoques no trabaja para mí en la versión 2.3.3.

    Para girar el mapa de bits hice esto:

    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);
  6. 0

    He comparado mi código para el tutorial de uno y lo que finalmente se fijo que estaba poniendo el siguiente código en mi AndroidManifext.xml:
    En el <activity> etiqueta:

    android:screenOrientation="landscape"
    android:configChanges="keyboardHidden|orientation">
  7. 0
    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();
    }
    }

Dejar respuesta

Please enter your comment!
Please enter your name here