Search code examples
androidimagegalleryportrait

Need help to show image from gallery only in portrait mode Android


I am a new bie in Android development. Please bare with my english. I struck with a problem where I am unable to show image from gallery in portrait mode,it is showing in landscape mode.Here is the code for your reference,Could you please help me to solve this issue.Thanks in Advance.

What I tried sofar is, I have gone through the below stackoverflow answers to the same issue and tried to place the same code in my class but the image still sits in landscape mode only. Stackvoerflow links I followed are: 1.Open Image from Gallery Only in Potrait mode

2.http://codereply.com/answer/5xf8di/android-detect-image-orientation-portrait-landscape-picked-gallery-setting-imageview.html

3.Android: Bitmaps loaded from gallery are rotated in ImageView

public class FragmentTab1 extends Fragment  {
     RelativeLayout homes; 
     private static int RESULT_LOAD_IMAGE = 1;
        ImageView bitmapView;
        BitmapFactory.Options options;
        String filePath;
        Button rot;
    private int mDegree = 0;
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            // Get the view from fragmenttab1.xml
            View ima = inflater.inflate(R.layout.fragmenttab1, container, false);

            homes = (RelativeLayout) ima.findViewById(R.id.hmt);
                       bitmapView = (ImageView) ima.findViewById(R.id.image);
            homes.setOnLongClickListener(new OnLongClickListener() {

                @Override
                public boolean onLongClick(View v) {
                    Intent i = new Intent(
                            Intent.ACTION_PICK,
                            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                    startActivityForResult(i, RESULT_LOAD_IMAGE);   
                    return false;
                }
            });
            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
            final String filePath = prefs.getString("profilePic", "");
            if (!filePath.equals("")) {
                bitmapView = (ImageView) ima.findViewById(R.id.image);
                bitmapView.setImageBitmap(BitmapLoaderf.loadBitmap(filePath, 500, 500));
                bitmapView.setScaleType(ImageView.ScaleType.FIT_XY);
                }


            return ima;
        }
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if (requestCode == RESULT_LOAD_IMAGE && resultCode == getActivity().RESULT_OK && null != data) {
                Uri picUri = data.getData();
                String[] filePathColumn = {MediaStore.Images.Media.DATA};
                Cursor cursor = getActivity().getContentResolver().query(picUri,
                        filePathColumn, null, null, null);
                cursor.moveToFirst();
                int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                filePath = cursor.getString(columnIndex);
                cursor.close();
                bitmapView.setImageBitmap(BitmapLoaderf.loadBitmap(filePath, 500, 500));
                bitmapView.setScaleType(ImageView.ScaleType.FIT_XY);

            SharedPreferences shre = PreferenceManager.getDefaultSharedPreferences(getActivity());
            Editor edit = shre.edit();
            edit.putString("profilePic", filePath);
            edit.commit();
            }
        }

}
    class BitmapLoaderf {
        public static int getScale(int originalWidth, int originalHeight,
                                   final int requiredWidth, final int requiredHeight) {
            //a scale of 1 means the original dimensions
            //of the image are maintained
            int scale = 1;

            //calculate scale only if the height or width of
            //the image exceeds the required value.
            if ((originalWidth > requiredWidth) || (originalHeight > requiredHeight)) {
                //calculate scale with respect to
                //the smaller dimension
                if (originalWidth < originalHeight)
                    scale = Math.round((float) originalWidth / requiredWidth);
                else
                    scale = Math.round((float) originalHeight / requiredHeight);

            }

            return scale;
        }

        public static BitmapFactory.Options getOptions(String filePath,
                                                       int requiredWidth, int requiredHeight) {

            BitmapFactory.Options options = new BitmapFactory.Options();
            //setting inJustDecodeBounds to true
            //ensures that we are able to measure
            //the dimensions of the image,without
            //actually allocating it memory
            options.inJustDecodeBounds = true;

            //decode the file for measurement
            BitmapFactory.decodeFile(filePath, options);

            //obtain the inSampleSize for loading a
            //scaled down version of the image.
            //options.outWidth and options.outHeight
            //are the measured dimensions of the
            //original image
            options.inSampleSize = getScale(options.outWidth,
                    options.outHeight, requiredWidth, requiredHeight);

            //set inJustDecodeBounds to false again
            //so that we can now actually allocate the
            //bitmap some memory
            options.inJustDecodeBounds = false;

            return options;

        }


        public static Bitmap loadBitmap(String filePath,
                                        int requiredWidth, int requiredHeight) {


            BitmapFactory.Options options = getOptions(filePath,
                    requiredWidth, requiredHeight);

            return BitmapFactory.decodeFile(filePath, options);
        }
    }

Solution

  • This is what I usually do :

    public class ExifUtils {
    public static Bitmap rotateBitmap(String src, Bitmap bitmap) {
        try {
            int orientation = getExifOrientation(src);
    
            if (orientation == 1) {
                return bitmap;
            }
    
            Matrix matrix = new Matrix();
            switch (orientation) {
            case 2:
                matrix.setScale(-1, 1);
                break;
            case 3:
                matrix.setRotate(180);
                break;
            case 4:
                matrix.setRotate(180);
                matrix.postScale(-1, 1);
                break;
            case 5:
                matrix.setRotate(90);
                matrix.postScale(-1, 1);
                break;
            case 6:
                matrix.setRotate(90);
                break;
            case 7:
                matrix.setRotate(-90);
                matrix.postScale(-1, 1);
                break;
            case 8:
                matrix.setRotate(-90);
                break;
            default:
                return bitmap;
            }
    
            try {
                Bitmap oriented = Bitmap.createBitmap(bitmap, 0, 0,
                        bitmap.getWidth(), bitmap.getHeight(), matrix, true);
                bitmap.recycle();
                return oriented;
            } catch (OutOfMemoryError e) {
                e.printStackTrace();
                return bitmap;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    
        return bitmap;
    }
    
    private static int getExifOrientation(String src) throws IOException {
        int orientation = 1;
    
        try {
            /**
             * if your are targeting only api level >= 5 ExifInterface exif =
             * new ExifInterface(src); orientation =
             * exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
             */
            if (Build.VERSION.SDK_INT >= 5) {
                Class<?> exifClass = Class
                        .forName("android.media.ExifInterface");
                Constructor<?> exifConstructor = exifClass
                        .getConstructor(new Class[] { String.class });
                Object exifInstance = exifConstructor
                        .newInstance(new Object[] { src });
                Method getAttributeInt = exifClass.getMethod("getAttributeInt",
                        new Class[] { String.class, int.class });
                java.lang.reflect.Field tagOrientationField = exifClass
                        .getField("TAG_ORIENTATION");
                String tagOrientation = (String) tagOrientationField.get(null);
                orientation = (Integer) getAttributeInt.invoke(exifInstance,
                        new Object[] { tagOrientation, 1 });
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    
        return orientation;
    }
    }
    

    Then in the main Activity you call it like this:

    image.setImageBitmap(ExifUtils.rotateBitmap(path, decodeSampledBitmap(new File(path), 400, 400)));
    
    
    public Bitmap decodeSampledBitmap(File res, int reqWidth, int reqHeight) {
        if (res != null) {
            // First decode with inJustDecodeBounds=true to check dimensions
            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            try {
                FileInputStream stream2 = new FileInputStream(res);
    
                BitmapFactory.decodeStream(stream2, null, options);
    
                stream2.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            // Calculate inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
            o2.inJustDecodeBounds = false;
            FileInputStream stream = null;
            try {
                stream = new FileInputStream(res);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            Bitmap bitmap = BitmapFactory.decodeStream(stream, null, o2);
            try {
                stream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return bitmap;
        } else
            return null;
    }
    
    public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
    
        if (height > reqHeight || width > reqWidth) {
    
            final int halfHeight = height / 2;
            final int halfWidth = width / 2;
    
            // Calculate the largest inSampleSize value that is a power of 2 and keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }
    
        return inSampleSize;
    }
    

    In this code you extract the bitmap from the file path, give it a certain height and width and pass it to the ExifUtils to show the bitmap in the correct way.

    I think this wraps your class and more.

    If you need anymore help I am more than ready to offer