Android: la vista previa de la cámara está de lado

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

Puedo hacer que todo funcione bien, se crea la superficie, se establece la superficie y se muestra la superficie.

Sin embargo, siempre muestra la imagen en un ángulo incorrecto de 90 grados en el modo vertical.

Tal como en la imagen:

texto alternativo

Soy consciente de que usar el siguiente código establecerá la imagen correcta:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 

Sin embargo, tengo la vista previa dentro de una actividad que tiene otros elementos y no tiene sentido que mi actividad se muestre en modo horizontal. (Está deshabilitado por defecto)

Entonces, me preguntaba ¿hay alguna forma de cambiar la orientación de la vista previa? ¿Y dejar el rest de mi actividad correctamente visualizada en modo vertical?

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

    Este problema parecía comenzar como un error con cierto hardware , pero puede ser superado usando la llamada a mCamera.setDisplayOrientation (grados) disponible en API 8. Así que así es como lo implemento:

     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 estaba en un HTC Desire y tuve que poner inicialmente las declaraciones de registro en cada una de las comprobaciones de rotación para decir qué era la rotación y luego depurarla en el dispositivo y ver la salida de logCat mientras rotaba el dispositivo. Para el HTC Desire, 0 era el teléfono como era de esperar (retrato), 90 grados giraba el teléfono 90 ° EN SENTIDO CONTRARIO A LAS MANECILLAS DEL RELOJ (había supuesto que habría sido en el sentido de las agujas del reloj). En el código verá que no necesité hacer ninguna rotación de pantalla cuando el teléfono estaba a 90 o 180 grados, el dispositivo parecía manejarlo solo. Solo un punto no funciona correctamente: la rotación de 270 grados es cuando gira el dispositivo 90 grados en el sentido de las agujas del reloj y la rotación de la pantalla contrarresta eso, pero si gira el dispositivo 270 grados en sentido antihorario, no parece compensarlo adecuadamente.

    PS Note el swapover de ancho y alto en las rotaciones apropiadas.

    intente configurar la orientación de la pantalla. Soluciona mi problema

      mCamera.setDisplayOrientation(90); 
      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

    Lo hice siguiendo el consejo de mCamera.setDisplayOrientation (90); pero también rotó el bitmap porque por alguna razón los otros enfoques no funcionan para mí en la versión 2.3.3.

    Para rotar el bitmap 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); 

    Estoy teniendo problemas con la cámara frontal (problema al revés). Entonces uso este método

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

    He comparado mi código con el tutorial y lo que finalmente solucionó fue poner el siguiente código en mi AndroidManifext.xml: en la etiqueta :

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

    Esta pieza de línea me funcionó a la perfección

      static { ORIENTATIONS.append(Surface.ROTATION_0, 90); ORIENTATIONS.append(Surface.ROTATION_90, 180); ORIENTATIONS.append(Surface.ROTATION_180, 270); ORIENTATIONS.append(Surface.ROTATION_270, 360); }