Android die een afbeelding uit de galerij haalt, wordt geroteerd

Ik probeer gebruikers een profielfoto uit de galerij te laten selecteren. Mijn probleem is dat sommige foto’s naar rechts gedraaid zijn.

Ik start de afbeeldingkiezer als volgt:

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

Ik krijg de afbeelding van onActivityResult als volgt:

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

Hoe kan ik ervoor zorgen dat afbeeldingen niet worden gedraaid?

UPDATE:

Na enkele van de nuttige antwoorden die ik heb gekregen, ben ik erin geslaagd om de volgende werkende oplossing te bedenken (het is gewoon een werkende code, niet goed geschreven). Ik zou graag uw feedback ontvangen over hoe ik het kan verbeteren!

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

Antwoord 1, autoriteit 100%

U kunt ExifInterfacegebruiken om de oriëntatie te wijzigen:

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

Om het absolute pad van uw afbeeldingen uit hun uri te krijgen, controleert u dit antwoord


Antwoord 2, autoriteit 19%

2 Eénregelige oplossingen met Picasso en glijdende bibliotheek

Na veel tijd te hebben besteed aan veel oplossingen voor het beeldrotatieprobleem, heb ik eindelijk twee eenvoudige oplossingen gevonden. We hoeven geen extra werkzaamheden uit te voeren.

De Picasso-bibliotheek gebruikenhttps://github.com/square/picasso

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

Glide-bibliotheek gebruikenhttps://github.com/bumptech/glide

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

Picasso en Glide zijn een zeer krachtige bibliotheek voor het verwerken van afbeeldingen die in uw app zijn opgenomen. Het leest de EXIF-gegevens van afbeeldingen en roteert de afbeeldingen automatisch.


Antwoord 3, autoriteit 13%

Ik gebruik deze statische methoden. De eerste bepaalt de oriëntatie en de tweede roteert de afbeelding en verkleint deze indien nodig.

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

Other episodes