voltear una studio seleccionar ruta photoutils para obtener manipular imagenes imagen galeria fotos espejo desde codigo cargar android android-gallery

una - seleccionar imagen de galeria android studio



Android obtiene una imagen de la galería viene girada (5)

Estoy intentando que los usuarios seleccionen una imagen de perfil de la galería. Mi problema es que algunas fotos vienen rotadas hacia la derecha.

Comienzo el selector de imágenes así:

Intent photoPickerIntent = new Intent(); photoPickerIntent.setType("image/*"); photoPickerIntent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(photoPickerIntent, "Select profile picture"), Global.CODE_SELECT_PICTURE);

Obtengo la imagen de onActivityResult así:

Uri selectedPicture = data.getData(); profilePic = MediaStore.Images.Media.getBitmap(activity.getContentResolver(), selectedPicture);

¿Cómo puedo hacer que las imágenes no se roten?

ACTUALIZAR:

Siguiendo algunas de las respuestas útiles que he recibido, logré encontrar la siguiente solución de trabajo (es solo un código de trabajo, no está bien escrito). ¡Me encantaría recibir sus comentarios sobre cómo puedo mejorarlo!

public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK && requestCode == Global.CODE_SELECT_PICTURE) { // Get selected gallery image Uri selectedPicture = data.getData(); // Get and resize profile image String[] filePathColumn = {MediaStore.Images.Media.DATA}; Cursor cursor = activity.getContentResolver().query(selectedPicture, filePathColumn, null, null, null); cursor.moveToFirst(); int columnIndex = cursor.getColumnIndex(filePathColumn[0]); String picturePath = cursor.getString(columnIndex); cursor.close(); Bitmap loadedBitmap = BitmapFactory.decodeFile(picturePath); ExifInterface exif = null; try { File pictureFile = new File(picturePath); exif = new ExifInterface(pictureFile.getAbsolutePath()); } catch (IOException e) { e.printStackTrace(); } int orientation = ExifInterface.ORIENTATION_NORMAL; if (exif != null) orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: loadedBitmap = rotateBitmap(loadedBitmap, 90); break; case ExifInterface.ORIENTATION_ROTATE_180: loadedBitmap = rotateBitmap(loadedBitmap, 180); break; case ExifInterface.ORIENTATION_ROTATE_270: loadedBitmap = rotateBitmap(loadedBitmap, 270); break; } } } public static Bitmap rotateBitmap(Bitmap bitmap, int degrees) { Matrix matrix = new Matrix(); matrix.postRotate(degrees); return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); }


Aquí está el enfoque ExifInterface escrito en Kotlin:

fun modifyOrientation(bitmap: Bitmap, image_absolute_path: String): Bitmap { val ei = ExifInterface(image_absolute_path) val orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL) return when (orientation) { ExifInterface.ORIENTATION_ROTATE_90 -> rotateImage(bitmap, 90.toFloat()) ExifInterface.ORIENTATION_ROTATE_180 -> rotateImage(bitmap, 180.toFloat()) ExifInterface.ORIENTATION_ROTATE_270 -> rotateImage(bitmap, 270.toFloat()) ExifInterface.ORIENTATION_FLIP_HORIZONTAL -> flipImage(bitmap, true, false) ExifInterface.ORIENTATION_FLIP_VERTICAL -> flipImage(bitmap, false, true) else -> bitmap } } private fun rotateImage(bitmap: Bitmap, degrees: Float): Bitmap { val matrix = Matrix() matrix.postRotate(degrees) return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true) } private fun flipImage(bitmap: Bitmap, horizontal: Boolean, vertical: Boolean): Bitmap { val matrix = Matrix() matrix.preScale((if (horizontal) -1 else 1).toFloat(), (if (vertical) -1 else 1).toFloat()) return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true) }


Lo hago de esta manera:

public void browseClick(View view) { view.startAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.button_animation)); Intent i = new Intent( Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(i, RESULT_LOAD_IMAGE); }

Y el resultado en el que se marca la orientación le interesará más:

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) { Uri selectedImage = data.getData(); String[] filePathColumn = { MediaStore.Images.Media.DATA }; Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null); cursor.moveToFirst(); int columnIndex = cursor.getColumnIndex(filePathColumn[0]); String picturePath = cursor.getString(columnIndex); cursor.close(); Bitmap loadedBitmap = BitmapFactory.decodeFile(picturePath); Matrix matrix = new Matrix(); Bitmap scaledBitmap; if (loadedBitmap.getWidth() >= loadedBitmap.getHeight()){ matrix.setRectToRect(new RectF(0, 0, loadedBitmap.getWidth(), loadedBitmap.getHeight()), new RectF(0, 0, 400, 300), Matrix.ScaleToFit.CENTER); scaledBitmap = Bitmap.createBitmap(loadedBitmap, 0, 0, loadedBitmap.getWidth(), loadedBitmap.getHeight(), matrix, true); } else{ matrix.setRectToRect(new RectF(0, 0, loadedBitmap.getWidth(), loadedBitmap.getHeight()), new RectF(0, 0, 300, 400), Matrix.ScaleToFit.CENTER); scaledBitmap = Bitmap.createBitmap(loadedBitmap, 0, 0, loadedBitmap.getWidth(), loadedBitmap.getHeight(), matrix, true); } File file = new File(getExternalCacheDir(), "image.jpg"); try { FileOutputStream out = new FileOutputStream(file); scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out); out.flush(); out.close(); } catch (Exception e) { Log.e("Image", "Convert"); } imageView.setImageBitmap(scaledBitmap); } }


Puede usar ExifInterface para modificar la orientación:

public static Bitmap modifyOrientation(Bitmap bitmap, String image_absolute_path) throws IOException { ExifInterface ei = new ExifInterface(image_absolute_path); int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: return rotate(bitmap, 90); case ExifInterface.ORIENTATION_ROTATE_180: return rotate(bitmap, 180); case ExifInterface.ORIENTATION_ROTATE_270: return rotate(bitmap, 270); case ExifInterface.ORIENTATION_FLIP_HORIZONTAL: return flip(bitmap, true, false); case ExifInterface.ORIENTATION_FLIP_VERTICAL: return flip(bitmap, false, true); default: return bitmap; } } public static Bitmap rotate(Bitmap bitmap, float degrees) { Matrix matrix = new Matrix(); matrix.postRotate(degrees); return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); } public static Bitmap flip(Bitmap bitmap, boolean horizontal, boolean vertical) { Matrix matrix = new Matrix(); matrix.preScale(horizontal ? -1 : 1, vertical ? -1 : 1); return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); }

Para obtener la ruta absoluta de sus imágenes desde su uri, verifique esta respuesta


Yo uso estos métodos estáticos. El primero determina la orientación y el segundo gira la imagen, encogiéndola según sea necesario.

public static int getOrientation(Context context, Uri photoUri) { Cursor cursor = context.getContentResolver().query(photoUri, new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null); if (cursor == null || cursor.getCount() != 1) { return 90; //Assuming it was taken portrait } cursor.moveToFirst(); return cursor.getInt(0); } /** * Rotates and shrinks as needed */ public static Bitmap getCorrectlyOrientedImage(Context context, Uri photoUri, int maxWidth) throws IOException { InputStream is = context.getContentResolver().openInputStream(photoUri); BitmapFactory.Options dbo = new BitmapFactory.Options(); dbo.inJustDecodeBounds = true; BitmapFactory.decodeStream(is, null, dbo); is.close(); int rotatedWidth, rotatedHeight; int orientation = getOrientation(context, photoUri); if (orientation == 90 || orientation == 270) { Log.d("ImageUtil", "Will be rotated"); rotatedWidth = dbo.outHeight; rotatedHeight = dbo.outWidth; } else { rotatedWidth = dbo.outWidth; rotatedHeight = dbo.outHeight; } Bitmap srcBitmap; is = context.getContentResolver().openInputStream(photoUri); Log.d("ImageUtil", String.format("rotatedWidth=%s, rotatedHeight=%s, maxWidth=%s", rotatedWidth, rotatedHeight, maxWidth)); if (rotatedWidth > maxWidth || rotatedHeight > maxWidth) { float widthRatio = ((float) rotatedWidth) / ((float) maxWidth); float heightRatio = ((float) rotatedHeight) / ((float) maxWidth); float maxRatio = Math.max(widthRatio, heightRatio); Log.d("ImageUtil", String.format("Shrinking. maxRatio=%s", maxRatio)); // Create the bitmap from file BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = (int) maxRatio; srcBitmap = BitmapFactory.decodeStream(is, null, options); } else { Log.d("ImageUtil", String.format("No need for Shrinking. maxRatio=%s", 1)); srcBitmap = BitmapFactory.decodeStream(is); Log.d("ImageUtil", String.format("Decoded bitmap successful")); } is.close(); /* * if the orientation is not 0 (or -1, which means we don''t know), we * have to do a rotation. */ if (orientation > 0) { Matrix matrix = new Matrix(); matrix.postRotate(orientation); srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(), srcBitmap.getHeight(), matrix, true); } return srcBitmap; }


2 soluciones de una línea utilizando 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.

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

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

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

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

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.