4

Picture was taken successfully with camera but in portrait mode on samsung galaxy s3 the picture gets rotated. How can i solve this issue. Camera intent is as follows:

Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(xdestination));
        startActivityForResult(intent, CAMERA_PIC_REQUEST);

In activity for result

 if (requestCode==CAMERA_PIC_REQUEST){

            //  Bitmap bm = (Bitmap) data.getExtras().get("data"); 

                Uri photo_uri = Uri.fromFile(xdestination);

                Editer.PHOTO_FROM=11;

                Bitmap decodeSampledBitmapFromFile=null;
                try {
                    decodeSampledBitmapFromFile = decodeUri(photo_uri);
                } catch (FileNotFoundException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }

                ByteArrayOutputStream bytes = new ByteArrayOutputStream();
                decodeSampledBitmapFromFile.compress(Bitmap.CompressFormat.JPEG,100, bytes);

                File f  = new File(Environment.getExternalStorageDirectory(), "user_image.jpg");

                try {

                    if(f.exists())
                        f.delete();

                    f.createNewFile();

                    FileOutputStream fo = new FileOutputStream(f);
                    fo.write(bytes.toByteArray());
                    fo.close();

                } catch (IOException e) {

                    e.printStackTrace( );
                    Log.d("ERROR", e.toString());
                }

            }
user3115198
  • 107
  • 2
  • 3
  • 8
  • I too had a same problem and i rotate the picture after capturing it. – InnocentKiller Feb 14 '14 at 10:30
  • can you tell me how you rotate the picture? post your codes if possible or part of it – user3115198 Feb 14 '14 at 10:36
  • try my below code and let me know whether it is working for you or not. – InnocentKiller Feb 14 '14 at 10:47
  • good but not for my issue, i need to rotate the image saved in path File f = new File(Environment.getExternalStorageDirectory(), "user_image.jpg"); – user3115198 Feb 14 '14 at 10:48
  • Then just change the path, Check my updated answer. – InnocentKiller Feb 14 '14 at 10:49
  • i need to change the rotation of picture saved in directory File f = new File(Environment.getExternalStorageDirectory(), "user_image.jpg"); not to set on imageview dear. – user3115198 Feb 14 '14 at 10:59
  • 3
    Possible duplicate of [Why does an image captured using camera intent gets rotated on some devices on Android?](https://stackoverflow.com/questions/14066038/why-does-an-image-captured-using-camera-intent-gets-rotated-on-some-devices-on-a) – bummi Dec 04 '17 at 11:03

5 Answers5

19

Pass your taken picture and SDCard path of that picture into the following method which will return the correct oriented picture...

private Bitmap imageOreintationValidator(Bitmap bitmap, String path) {

    ExifInterface ei;
    try {
        ei = new ExifInterface(path);
        int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_NORMAL);
        switch (orientation) {
        case ExifInterface.ORIENTATION_ROTATE_90:
            bitmap = rotateImage(bitmap, 90);
            break;
        case ExifInterface.ORIENTATION_ROTATE_180:
            bitmap = rotateImage(bitmap, 180);
            break;
        case ExifInterface.ORIENTATION_ROTATE_270:
            bitmap = rotateImage(bitmap, 270);
            break;
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    return bitmap;
}

private Bitmap rotateImage(Bitmap source, float angle) {

    Bitmap bitmap = null;
    Matrix matrix = new Matrix();
    matrix.postRotate(angle);
    try {
        bitmap = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(),
                matrix, true);
    } catch (OutOfMemoryError err) {
        err.printStackTrace();
    }
    return bitmap;
}
Hamid Shatu
  • 9,664
  • 4
  • 30
  • 41
  • sorry i did decodeSampledBitmapFromFile = imageOreintationValidator(decodeSampledBitmapFromFile,f.getPath()); decodeSampledBitmapFromFile.compress(Bitmap.CompressFormat.JPEG,100, bytes); but no effect image is still in landscape – user3115198 Feb 14 '14 at 12:03
  • how to get "String path" from camera? – Heena Arora Jan 18 '18 at 08:16
0

Try it like below.

File photo = new File(Environment.getExternalStorageDirectory(), "user_image.jpg");
        if (photo.exists()) {
            Bitmap myBitmap = BitmapFactory.decodeFile(photo
                    .getAbsolutePath());
            imageView.setImageBitmap(myBitmap);
            imageView.setRotation(90);
        }

Step 1: Give a full path of your photo like File photo = new File(Environment.getExternalStorageDirectory() , "Face.jpg");

Step 2: Check whether photo is exist or not if yes then set it to image view and rotate it to 90 degree.

InnocentKiller
  • 5,234
  • 7
  • 36
  • 84
0

Use :

public int getCameraPhotoOrientation(Context context, Uri imageUri, String imagePath){
    int rotate = 0;
    try {
        context.getContentResolver().notifyChange(imageUri, null);
        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;
        }

        Log.i("RotateImage", "Exif orientation: " + orientation);
        Log.i("RotateImage", "Rotate value: " + rotate);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return rotate;
}
Dimitri
  • 1,924
  • 9
  • 43
  • 65
0

You have no choice but read the image, rotate it and write the result back to SD card. The straightforward approach, using BitmapFactory, will easily run into OutOfMemory exception.

Alternatively, you can use JPEG lossless rotation, using jpegtran.

On SourceForge, there is a Java open source class LLJTran. The Android port is on GitHub.

Community
  • 1
  • 1
Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
0

Today I faced this problem. I know I'm late, but just in case someone needs it. In my case, if I pass the Uri inside the camera intent, then the output file was rotated. That is,

fun takePhoto() {
        val intent = Intent(android.media.action.IMAGE_CAPTURE)
        intent.putExtra(MediaStore.EXTRA_OUTPUT, 
                Uri.fromFile(xdestination)) // <-- this line is the culprit for me
        startActivityForResult(intent, CAMERA_PIC_REQUEST)
}

Then inside onActivity result, you get the bitmap rotated. I don't know why that happened.

So I didnot provide the Uri to the intent. That is I wrote this:

fun takePhoto() {
        val intent = Intent(android.media.action.IMAGE_CAPTURE)
        startActivityForResult(intent, CAMERA_PIC_REQUEST)
}

Therefore, inside onActivityResult I got the returned image as bitmap. Then I manually saved that bitmap inside the desired file / Uri.


  override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode == PHOTO_CAPTURE_WITH_CAMERA_REQ_CODE && resultCode == RESULT_OK) {
      // 1. handle the image as normal bitmap
      val photo: Bitmap? = data?.extras?.get("data") as Bitmap;
      // handleImage(SharedData.pendingPhotoUri.pop())
      if (photo != null) {
        // inside handle camera
        handleCameraImage(photo)
      };
    }
  }

  private fun handleCameraImage(inputBitmap: Bitmap) {
    //2. according to previous implementation, this uri should be the final output image file.

    // 3. save the original bitmap in a temp image file
    val tempBitmapFile: String = requireActivity().cacheDir.absolutePath +"/temp_photo_"+System.currentTimeMillis();
    val fOuttemp: FileOutputStream = FileOutputStream(tempBitmapFile);
    inputBitmap.compress(Bitmap.CompressFormat.PNG, 85, fOuttemp);
    fOuttemp.flush();
    fOuttemp.close();

    // 4. use ExifInterface to make sure the photo is in right orientation.
    val exifInterface: ExifInterface = ExifInterface(tempBitmapFile);
    val orientation: Int = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
        ExifInterface.ORIENTATION_UNDEFINED);

    Timber.tag(TAG).e("orientation == " + orientation);
    var matrix = Matrix();
    var isRotationNeeded: Boolean = true;
    when(orientation){
      ExifInterface.ORIENTATION_NORMAL -> {
        Timber.tag(TAG).e("when ExifInterface.ORIENTATION_NORMAL");
        // do nothing I guess
        isRotationNeeded = false;
      }
      ExifInterface.ORIENTATION_ROTATE_90 -> {
        Timber.tag(TAG).e("when ExifInterface.ORIENTATION_ROTATE_90");
        matrix.setRotate(90f);
      }
      ExifInterface.ORIENTATION_ROTATE_180 -> {
        Timber.tag(TAG).e("when ExifInterface.ORIENTATION_ROTATE_180");
        matrix.setRotate(180f);
      }
      ExifInterface.ORIENTATION_ROTATE_270 -> {
        Timber.tag(TAG).e("when ExifInterface.ORIENTATION_ROTATE_270");
        matrix.setRotate(270f);
      }
      else -> {
        Timber.tag(TAG).e("when else");
        isRotationNeeded = false;
      }
    }

    // if in wrong orientation,
    //    rotate image and save it in the file from step 2.
    // else save the original image in the file from step 2.
    lateinit var outputBitmap: Bitmap;
    if(!isRotationNeeded) {
      outputBitmap = inputBitmap;
    }else{
      outputBitmap = Bitmap.createBitmap(inputBitmap, 0, 0, inputBitmap.width,
          inputBitmap.height, matrix, true);
    }

    val outputBitmapfile: File = File("your_awesome_file");

    val fOut: FileOutputStream = FileOutputStream(outputBitmapfile);
    outputBitmap.compress(Bitmap.CompressFormat.PNG, 85, fOut);
    fOut.flush();
    fOut.close();

    var outputPhotoUri:Uri = getUriForFile(requireActivty(), outputBitmapfile);



    // 5. finally use this photo / Uri to do whatever you want

  }

  fun getUriForFile(context: Context, file: File?): Uri? {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N || Config.ONLY_INTERNAL_STORAGE) {
      try {
        val destCopiedTempFile = File(context.getExternalFilesDir(null).toString() + File.separator + "temp")
        FileBackend.copy(file, destCopiedTempFile)
        FileProvider.getUriForFile(context,
            BuildConfig.APPLICATION_ID + ".fileprovider", destCopiedTempFile)
      } catch (e: IllegalArgumentException) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
          throw SecurityException(e)
        } else {
          Uri.fromFile(file)
        }
      }
    } else {
      Uri.fromFile(file)
    }
  }

This worked for me.

Qazi Fahim Farhan
  • 2,066
  • 1
  • 14
  • 26