Android getting an image from gallery comes rotated

后端 未结 6 1264
闹比i
闹比i 2020-11-30 20:08

I am trying to let users select a profile picture from gallery. My issue is that some pictures come as rotated to the right.

I start the image picker like so:

<
相关标签:
6条回答
  • 2020-11-30 20:40

    I do it this way:

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

    And the result where the orientation is checked will interest you most:

    @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);
        }
    }
    
    0 讨论(0)
  • 2020-11-30 20:49

    You could use ExifInterface to modify the orientation:

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

    In order to get absolute path of your images from their uri, check this answer

    0 讨论(0)
  • 2020-11-30 20:50

    I use these static methods. The first determines the orientation and the second rotates the image shrinking it as needed.

    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;
            }
    
    0 讨论(0)
  • 2020-11-30 21:00

    2 One line solutions using Picasso and glide library

    After spending a lot of time with a lot of solutions for image rotation problem I finally found two simple solutions. We don't need to do any additional works.

    Using Picasso library https://github.com/square/picasso

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

    Using glide library https://github.com/bumptech/glide

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

    Picasso and Glide are a very powerful library for handling images in your app includes. It will read image EXIF data and auto-rotates the images.

    0 讨论(0)
  • 2020-11-30 21:03

    Here is the ExifInterface approach written in 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, 90f)
            ExifInterface.ORIENTATION_ROTATE_180 -> rotateImage(bitmap, 180f)
            ExifInterface.ORIENTATION_ROTATE_270 -> rotateImage(bitmap, 270f)
            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)
    }
    
    0 讨论(0)
  • 2020-11-30 21:06

    Using Picasso:

    Picasso.get().load("Your image path").into(Imageview);

    Picasso.with(this) is now replaced with

    Picasso.get()

    Picasso library : https://github.com/square/picasso

    Add : implementation 'com.squareup.picasso:picasso:2.71828' in build.gradle file

    Picasso will take care of image auto-rotation .

    0 讨论(0)
提交回复
热议问题