Search code examples
androidmatrixbitmapandroid-image

set image taken by camera in android?


I am working on an application where I take a picture in portrait orientation, The problem is when I then retrieve the image later on it is in landscape orientation (the picture has been rotated 90 degrees anti-clockwise). I have used below class but here orientation giving 0 (zero) every time. So, i can't figure out how to solve it.

public Bitmap rotateBitmapOrientation(String photoFilePath) {

// Create and configure BitmapFactory
BitmapFactory.Options bounds = new BitmapFactory.Options();
bounds.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file, bounds);
BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bm = BitmapFactory.decodeFile(file, opts);
// Read EXIF Data
ExifInterface exif = new ExifInterface(file);
String orientString = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
int orientation = orientString != null ? Integer.parseInt(orientString) : ExifInterface.ORIENTATION_NORMAL;
int rotationAngle = 0;
if (orientation == ExifInterface.ORIENTATION_ROTATE_90) rotationAngle = 90;
if (orientation == ExifInterface.ORIENTATION_ROTATE_180) rotationAngle = 180;
if (orientation == ExifInterface.ORIENTATION_ROTATE_270) rotationAngle = 270;
// Rotate Bitmap
Matrix matrix = new Matrix();
matrix.setRotate(rotationAngle, (float) bm.getWidth() / 2, (float) bm.getHeight() / 2);
Bitmap rotatedBitmap = Bitmap.createBitmap(bm, 0, 0, bounds.outWidth, bounds.outHeight, matrix, true);
// Return result
return rotatedBitmap;
}

Solution

  • There are several methods available over stackoverflow but i am using a mixture of them, if you want the image to be in the orientation it was captured you can use the following instruction and classes to do this

    Your onActivityResult

    @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            switch (requestCode) {
            case SELECT_IMAGE_FROM_CAMERA:
                if (requestCode == SELECT_IMAGE_FROM_CAMERA
                        && resultCode == RESULT_OK) {
                    int targetW = reviewImageView.getWidth();
                    int targetH = reviewImageView.getHeight();
                    BitmapFactory.Options bmOptions = new BitmapFactory.Options();
                    bmOptions.inJustDecodeBounds = true;
                    BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
                    int photoW = bmOptions.outWidth;
                    int photoH = bmOptions.outHeight;
    
                    // Determine how much to scale down the image
                    int scaleFactor = Math.min(photoW / targetW, photoH / targetH);
    
                    // Decode the image file into a Bitmap sized to fill the View
                    bmOptions.inJustDecodeBounds = false;
                    bmOptions.inSampleSize = scaleFactor;
                    bmOptions.inPurgeable = true;
    
                    Bitmap rotatedBitmap = decodeFile(new File(mCurrentPhotoPath),
                            photoW, photoH, getImageOrientation(mCurrentPhotoPath));
                    reviewImageView.setImageBitmap(rotatedBitmap);
                    uploadMessage.setVisibility(View.INVISIBLE);
                    UploadSuccess.setVisibility(View.INVISIBLE);
                } else if (requestCode == SELECT_IMAGE_FROM_CAMERA
                        && resultCode == RESULT_CANCELED) {
                    mCurrentPhotoPath = null;
                    photo = null;
                }
            }
            super.onActivityResult(requestCode, resultCode, data);
        }
    

    Helper Methods & Class

    public static int getImageOrientation(String imagePath) {
            int rotate = 0;
            try {
    
                File imageFile = new File(imagePath);
                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 (IOException e) {
                e.printStackTrace();
            }
            return rotate;
        }
    
    public static Bitmap decodeFile(File f, double REQUIRED_WIDTH,
                double REQUIRED_HEIGHT, int rotation) {
            try {
                if (REQUIRED_WIDTH == 0 || REQUIRED_HEIGHT == 0) {
                    return BitmapFactory.decodeFile(f.getAbsolutePath());
                } else {
                    BitmapFactory.Options o = new BitmapFactory.Options();
                    o.inJustDecodeBounds = true;
                    BitmapFactory.decodeFile(f.getAbsolutePath(), o);
    
                    o.inSampleSize = calculateInSampleSize(o, REQUIRED_WIDTH,
                            REQUIRED_HEIGHT);
    
                    o.inJustDecodeBounds = false;
                    o.inPurgeable = true;
                    Bitmap b = BitmapFactory.decodeFile(f.getAbsolutePath(), o);
                    if (rotation != 0)
                        b = rotate(b, rotation);
                    if (b.getWidth() > REQUIRED_WIDTH
                            || b.getHeight() > REQUIRED_HEIGHT) {
                        double ratio = Math.max((double) b.getWidth(),
                                (double) b.getHeight())
                                / (double) Math
                                        .min(REQUIRED_WIDTH, REQUIRED_HEIGHT);
    
                        return Bitmap.createScaledBitmap(b,
                                (int) (b.getWidth() / ratio),
                                (int) (b.getHeight() / ratio), true);
                    } else
                        return b;
                }
    
            } catch (Throwable ex) {
                ex.printStackTrace();
            }
            return null;
        }
    
    public static int calculateInSampleSize(BitmapFactory.Options options,
                double reqWidth, double 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) {
    
                // 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 ((height / inSampleSize) > reqHeight
                        || (width / inSampleSize) > reqWidth) {
                    inSampleSize *= 2;
                }
            }
            inSampleSize = Math.max(1, inSampleSize / 2);
            return inSampleSize;
        }
    
        public static Bitmap rotate(Bitmap b, int degrees) {
            if (degrees != 0 && b != null) {
                Matrix m = new Matrix();
                m.setRotate(degrees, (float) b.getWidth() / 2,
                        (float) b.getHeight() / 2);
                try {
                    Bitmap b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(),
                            b.getHeight(), m, true);
                    if (b != b2) {
                        b.recycle();
                        b = b2;
                    }
                } catch (OutOfMemoryError ex) {
                    // We have no memory to rotate. Return the original bitmap.
                }
            }
            return b;
        }
    

    You can customize each method according to your needs, my code follows android guideline, so its quite lengthy