studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones android camera android-intent orientation capture

para - manual de programacion android pdf



Problema de orientación de la cámara en Android (14)

Acabo de encontrar el mismo problema y lo usé para corregir la orientación:

public void fixOrientation() { if (mBitmap.getWidth() > mBitmap.getHeight()) { Matrix matrix = new Matrix(); matrix.postRotate(90); mBitmap = Bitmap.createBitmap(mBitmap , 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, true); } }

Si el ancho del mapa de bits es mayor que la altura, la imagen devuelta está en horizontal, por lo que la giro 90 grados.

Espero que ayude a alguien más con este problema.

Estoy construyendo una aplicación que utiliza la cámara para tomar fotos. Aquí está mi código fuente para hacer esto:

File file = new File(Environment.getExternalStorageDirectory(), imageFileName); imageFilePath = file.getPath(); Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); //Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); startActivityForResult(intent, ACTIVITY_NATIVE_CAMERA_AQUIRE);

En el método onActivityResult() , uso BitmapFactory.decodeStream() para recoger la imagen.

Cuando ejecuto mi aplicación en Nexus uno, funciona bien. Pero cuando uso Samsung Galaxy S o HTC Inspire 4G, la dirección de la imagen no es correcta.

  • Capture con el modo vertical, la imagen real (guardar en la tarjeta SD) siempre gira 90 grados.

Vista previa de la imagen después del disparo --------- Imagen real en la tarjeta SD

  • Capturar con modo horizontal, todo está bien.

Vista previa de la imagen después del disparo --------- Imagen real en la tarjeta SD


El código es funcionalmente para paisaje y retrato @frontCameraID = variable lo obtuvo el método clásico para mostrar la cámara deseada

@Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { if(holder.getSurface() == null) { return; } try{ camera.stopPreview(); } catch (Exception e){ } try{ int orientation = getDisplayOrientation(frontCameraID); Camera.Parameters parameters = camera.getParameters(); parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height); if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) { parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); } parameters.setRotation(rotationPicture); camera.setParameters(parameters); camera.setDisplayOrientation(orientation); camera.startPreview(); } catch (Exception e) { Log.i("ERROR", "Camera error changed: " + e.getMessage()); } }

Método para obtener orientación y rotación para guardar la imagen y orientación de la pantalla @result = orientación en la vista de vista previa de la cámara @rotationPicture = rotación necesaria para guardar la imagen correctamente

private int getDisplayOrientation(int cameraId) { android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); android.hardware.Camera.getCameraInfo(cameraId, info); int rotation = ((Activity) context).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; if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = (info.orientation + degrees) % 360; result = (360 - result) % 360; rotationPicture = (360 - result) % 360; } else { result = (info.orientation - degrees + 360) % 360; rotationPicture = result; } return result; }

Alguien pregunta sobre el código, por favor dígame.


Hay bastantes temas y problemas similares por aquí. Como no estás escribiendo tu propia cámara, creo que se reduce a esto:

algunos dispositivos rotan la imagen antes de guardarla, mientras que otros simplemente agregan la etiqueta de orientación en los datos exif de la foto.

Recomiendo verificar los datos exif de la foto y buscar particularmente

ExifInterface exif = new ExifInterface(SourceFileName); //Since API Level 5 String exifOrientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION);

Dado que la foto se muestra correctamente en su aplicación, no estoy seguro de dónde está el problema, pero esto definitivamente debe establecerlo en el camino correcto.


Hay dos cosas necesarias:

  1. La vista previa de la cámara necesita lo mismo que su rotación. Establezca esto por camera.setDisplayOrientation(result);

  2. Guarde la imagen capturada como la vista previa de su cámara. Hazlo a través de Camera.Parameters .

    int mRotation = getCameraDisplayOrientation(); Camera.Parameters parameters = camera.getParameters(); parameters.setRotation(mRotation); //set rotation to save the picture camera.setDisplayOrientation(result); //set the rotation for preview camera camera.setParameters(parameters);

Espero que ayude.


Intenta esto en callback de SurfaceChanged:

Camera.Parameters parameters=mCamera.getParameters(); if(this.getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT){ parameters.setRotation(90); }else{ parameters.setRotation(0); } mCamera.setParameters(parameters);


No más verificando los datos exif de la foto. Ve bien con Glide .

Google nos presentó una biblioteca de Image Loader para Android desarrollada por bumptech llamada Glide como una biblioteca recomendada por Google. Se ha utilizado en muchos proyectos de código abierto de Google hasta ahora, incluida la aplicación oficial Google I / O 2014.

Ejemplo: Glide.with (context) .load (uri) .into (imageview);

Para más: https://github.com/bumptech/glide


Otra opción es rotar el mapa de bits en la pantalla de resultados de esta manera:

ImageView img=(ImageView)findViewById(R.id.ImageView01); Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.refresh); // Getting width & height of the given image. int w = bmp.getWidth(); int h = bmp.getHeight(); // Setting post rotate to 90 Matrix mtx = new Matrix(); mtx.postRotate(90); // Rotating Bitmap Bitmap rotatedBMP = Bitmap.createBitmap(bmp, 0, 0, w, h, mtx, true); BitmapDrawable bmd = new BitmapDrawable(rotatedBMP); img.setImageDrawable(bmd);


Pruebe de esta manera: estática Uri image_uri; mapa de bits estático taken_image = null;

image_uri=fileUri; // file where image has been saved taken_image=BitmapFactory.decodeFile(image_uri.getPath()); try { ExifInterface exif = new ExifInterface(image_uri.getPath()); int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch(orientation) { case ExifInterface.ORIENTATION_ROTATE_90: taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200); RotateBitmap(taken_image, 90); break; case ExifInterface.ORIENTATION_ROTATE_180: taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200); RotateBitmap(taken_image, 180); break; case ExifInterface.ORIENTATION_ROTATE_270: taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200); RotateBitmap(taken_image, 270); break; case ExifInterface.ORIENTATION_NORMAL: taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200); RotateBitmap(taken_image, 0); break; } } catch (OutOfMemoryError e) { Toast.makeText(getActivity(),e+"/"memory exception occured/"",Toast.LENGTH_LONG).show(); } public Bitmap RotateBitmap(Bitmap source, float angle) { Matrix matrix = new Matrix(); matrix.postRotate(angle); round_Image = source; round_Image = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true); return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);

}


Solo encontramos el mismo problema aquí, el siguiente fragmento de código me funciona:

private static final String[] CONTENT_ORIENTATION = new String[] { MediaStore.Images.ImageColumns.ORIENTATION }; static int getExifOrientation(ContentResolver contentResolver, Uri uri) { Cursor cursor = null; try { cursor = contentResolver.query(uri, CONTENT_ORIENTATION, null, null, null); if (cursor == null || !cursor.moveToFirst()) { return 0; } return cursor.getInt(0); } catch (RuntimeException ignored) { // If the orientation column doesn''t exist, assume no rotation. return 0; } finally { if (cursor != null) { cursor.close(); } } }

Espero que esto ayude :)


También tengo este tipo de problema para algún dispositivo:

private void rotateImage(final String path) { Bitmap scaledBitmap = Bitmap.createScaledBitmap(Conasants.bm1, 1000, 700, true); Bitmap rotatedBitmap = null; try { ExifInterface ei = new ExifInterface(path); int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); Matrix matrix = new Matrix(); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: matrix.postRotate(90); rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true); break; case ExifInterface.ORIENTATION_ROTATE_180: matrix.postRotate(180); rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true); break; case ExifInterface.ORIENTATION_ROTATE_270: matrix.postRotate(270); rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true); break; default: rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true); break; } } catch (Throwable e) { e.printStackTrace(); } cropImage.setImageBitmap(rotatedBitmap); rotatedBitmap = null; Conasants.bm1 = null; }


dos soluciones de una línea usando Picasso y la biblioteca de planeo

Después de pasar mucho tiempo con una gran cantidad de soluciones para el problema de rotación de imágenes, finalmente encontré dos soluciones simples. No necesitamos hacer ningún trabajo adicional. Picasso y Glide son una biblioteca muy poderosa para el manejo de imágenes en su aplicación. Leerá los datos EXIF ​​de la imagen y auto-rota las imágenes.

Usando la biblioteca glide https://github.com/bumptech/glide

Glide.with(this).load("http url or sdcard url").into(imgageView);

Usando la biblioteca de Picasso https://github.com/square/picasso

Picasso.with(context).load("http url or sdcard url").into(imageView);


int rotate = 0; try { File imageFile = new File(sourcepath); ExifInterface exif = new ExifInterface( imageFile.getAbsolutePath()); int orientation = exif.getAttributeInt( ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_270: rotate = 270; break; case ExifInterface.ORIENTATION_ROTATE_180: rotate = 180; break; case ExifInterface.ORIENTATION_ROTATE_90: rotate = 90; break; } } catch (Exception e) { e.printStackTrace(); } Matrix matrix = new Matrix(); matrix.postRotate(rotate); bitmap = Bitmap.createBitmap(bitmap , 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);


public static int mOrientation = 1; OrientationEventListener myOrientationEventListener; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.takephoto); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); myOrientationEventListener = new OrientationEventListener(getApplicationContext()) { @Override public void onOrientationChanged(int o) { // TODO Auto-generated method stub if(!isTablet(getApplicationContext())) { if(o<=285 && o>=80) mOrientation = 2; else mOrientation = 1; } else { if(o<=285 && o>=80) mOrientation = 1; else mOrientation = 2; } } }; myOrientationEventListener.enable(); } public static boolean isTablet(Context context) { return (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE; } }

Espero que esto ayude. ¡Gracias!


public void setCameraPicOrientation(){ int rotate = 0; try { File imageFile = new File(mCurrentPhotoPath); ExifInterface exif = new ExifInterface( imageFile.getAbsolutePath()); int orientation = exif.getAttributeInt( ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_270: rotate = 270; break; case ExifInterface.ORIENTATION_ROTATE_180: rotate = 180; break; case ExifInterface.ORIENTATION_ROTATE_90: rotate = 90; break; } } catch (Exception e) { e.printStackTrace(); } Matrix matrix = new Matrix(); matrix.postRotate(rotate); int targetW = 640; int targetH = 640; /* Get the size of the image */ BitmapFactory.Options bmOptions = new BitmapFactory.Options(); bmOptions.inJustDecodeBounds = true; BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions); int photoW = bmOptions.outWidth; int photoH = bmOptions.outHeight; /* Figure out which way needs to be reduced less */ int scaleFactor = 1; if ((targetW > 0) || (targetH > 0)) { scaleFactor = Math.min(photoW/targetW, photoH/targetH); } /* Set bitmap options to scale the image decode target */ bmOptions.inJustDecodeBounds = false; bmOptions.inSampleSize = scaleFactor; bmOptions.inPurgeable = true; /* Decode the JPEG file into a Bitmap */ Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions); bitmap= Bitmap.createBitmap(bitmap , 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); /* Associate the Bitmap to the ImageView */ imageView.setImageBitmap(bitmap); }

Espero que esto ayude !! Gracias