tutorial studio permission open intent example development developer custom app android camera rotation

studio - ¿La imagen resultante de la cámara de Android debe rotarse después de la captura?



open camera android developer (4)

Estoy escribiendo una aplicación de Android que utiliza la cámara. Estoy configurando la orientación de la pantalla de la cámara en 90, mi actividad es en orientación vertical:

camera.setDisplayOrientation(90);

Obtengo una imagen de vista previa bien orientada, pero la imagen resultante se gira a -90 grados (en sentido contrario a las agujas del reloj) y

exif.getAttribute(ExifInterface.TAG_ORIENTATION)

devuelve ORIENTATION_NORMAL
¿Es el comportamiento esperado? ¿Debo rotar la imagen resultante después de la captura?

Dispositivo - Nexus S, API - 10


El problema es que la orientación de la cámara es un completo desastre (ya que está capturando una imagen) porque los OEM no se adhieren a la norma. Los teléfonos HTC hacen las cosas de una manera, los teléfonos Samsung lo hacen de una manera diferente, la línea Nexus parece adherirse sin importar qué proveedor, las ROM basadas en CM7 creo que siguen el estándar sin importar qué hardware, pero entienden la idea. Tienes que determinar qué hacer en función del teléfono / ROM. Vea la discusión aquí: Rotación inexplicable de la cámara de Android en la captura de algunos dispositivos (no en EXIF)


Prueba esto

try { File f = new File(imagePath); ExifInterface exif = new ExifInterface(f.getPath()); int orientation = exif.getAttributeInt( ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); int angle = 0; if (orientation == ExifInterface.ORIENTATION_ROTATE_90) { angle = 90; } else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) { angle = 180; } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) { angle = 270; } Matrix mat = new Matrix(); mat.postRotate(angle); BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2; Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f), null, options); bitmap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), mat, true); ByteArrayOutputStream outstudentstreamOutputStream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, outstudentstreamOutputStream); imageView.setImageBitmap(bitmap); } catch (IOException e) { Log.w("TAG", "-- Error in setting image"); } catch (OutOfMemoryError oom) { Log.w("TAG", "-- OOM Error in setting image"); }

Funcionará


Tuve el mismo problema que tú, pero lo arreglé.
Debes usar el mismo código:

Camera.Parameters parameters = camera.getParameters(); parameters.setRotation(90); camera.setParameters(parameters);

Espero que puedas usar este código también.


camera.setDisplayOrientation(90);

He codificado la aplicación sólo para el modo de retrato.

Hará que la cámara gire a 90 grados y esto puede resultar en que no sea adecuado para todos los dispositivos en Android. Para obtener la Vista previa correcta para todos los dispositivos Android, use el siguiente código que se encuentra en el sitio de los desarrolladores.

Debajo tienes que enviar tu actividad, cameraId = back es 0 y para la cámara frontal es 1

public static void setCameraDisplayOrientation(Activity activity, int cameraId, android.hardware.Camera camera) { android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); android.hardware.Camera.getCameraInfo(cameraId, info); int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); int degrees = 0; 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; //int currentapiVersion = android.os.Build.VERSION.SDK_INT; // do something for phones running an SDK before lollipop if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = (info.orientation + degrees) % 360; result = (360 - result) % 360; // compensate the mirror } else { // back-facing result = (info.orientation - degrees + 360) % 360; } camera.setDisplayOrientation(result); }

Así es como se configura el setDisplayOrientation para la cámara.

Ahora puede tener problemas para guardar la imagen capturada en la orientación correcta, que es un error en la API de la cámara para admitir todos los dispositivos en Android. Puedes superar usando los pasos a continuación

PLS NOTE EXIF ​​VALUE NO LE DA CORREGIR EL VALOR EN TODOS LOS DISPOSITIVOS, así que esto le ayudaría

int CameraEyeValue = setPhotoOrientation(CameraActivity.this, cameraFront==true ? 1:0); // CameraID = 1 : front 0:back

Usando el mismo concepto que usamos antes para DisplayOrientation

public int setPhotoOrientation(Activity activity, int cameraId) { android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); android.hardware.Camera.getCameraInfo(cameraId, info); int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); int degrees = 0; 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; // do something for phones running an SDK before lollipop if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = (info.orientation + degrees) % 360; result = (360 - result) % 360; // compensate the mirror } else { // back-facing result = (info.orientation - degrees + 360) % 360; } return result; }

Así que tu último método de PictureCallBack debería verse como

private PictureCallback getPictureCallback() { PictureCallback picture = new PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { //make a new picture file File pictureFile = getOutputMediaFile(); if (pictureFile == null) { return; } try { //write the file FileOutputStream fos = new FileOutputStream(pictureFile); Bitmap bm=null; // COnverting ByteArray to Bitmap - >Rotate and Convert back to Data if (data != null) { int screenWidth = getResources().getDisplayMetrics().widthPixels; int screenHeight = getResources().getDisplayMetrics().heightPixels; bm = BitmapFactory.decodeByteArray(data, 0, (data != null) ? data.length : 0); if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { // Notice that width and height are reversed Bitmap scaled = Bitmap.createScaledBitmap(bm, screenHeight, screenWidth, true); int w = scaled.getWidth(); int h = scaled.getHeight(); // Setting post rotate to 90 Matrix mtx = new Matrix(); int CameraEyeValue = setPhotoOrientation(AndroidCameraExample.this, cameraFront==true ? 1:0); // CameraID = 1 : front 0:back if(cameraFront) { // As Front camera is Mirrored so Fliping the Orientation if (CameraEyeValue == 270) { mtx.postRotate(90); } else if (CameraEyeValue == 90) { mtx.postRotate(270); } }else{ mtx.postRotate(CameraEyeValue); // CameraEyeValue is default to Display Rotation } bm = Bitmap.createBitmap(scaled, 0, 0, w, h, mtx, true); }else{// LANDSCAPE MODE //No need to reverse width and height Bitmap scaled = Bitmap.createScaledBitmap(bm, screenWidth, screenHeight, true); bm=scaled; } } // COnverting the Die photo to Bitmap ByteArrayOutputStream stream = new ByteArrayOutputStream(); bm.compress(Bitmap.CompressFormat.JPEG, 100, stream); byte[] byteArray = stream.toByteArray(); fos.write(byteArray); //fos.write(data); fos.close(); Toast toast = Toast.makeText(myContext, "Picture saved: " + pictureFile.getName(), Toast.LENGTH_LONG); toast.show(); } catch (FileNotFoundException e) { } catch (IOException e) { } //refresh camera to continue preview mPreview.refreshCamera(mCamera); mPreview.setCameraDisplayOrientation(CameraActivity.this,GlobalCameraId,mCamera); } }; return picture; }

Como funciona solo para el modo de retrato usando la cámara frontal y trasera La imagen se gira solo al modo de retrato con la orientación vertical correcta en todos los dispositivos Android.

Para LandScape puede hacer esto como referencia y realizar cambios en el bloque de abajo

if(cameraFront) { // As Front camera is Mirrored so Fliping the Orientation if (CameraEyeValue == 270) { mtx.postRotate(90); //change Here } else if (CameraEyeValue == 90) { mtx.postRotate(270);//change Here } }else{ mtx.postRotate(CameraEyeValue); // CameraEyeValue is default to Display Rotation //change Here }