17

I'm working at an application in android which uses camera to take photos.For starting the camera I'm using an intent ACTION_IMAGE_CAPTURE like this:

Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File image=new File(Environment.getExternalStorageDirectory(),"PhotoContest.jpg");
        camera.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(image));
        imageUri=Uri.fromFile(image);
        startActivityForResult(camera,1);

public void onActivityResult(int requestCode, int resultCode, Intent data){
    super.onActivityResult(requestCode, resultCode, data);
    switch(requestCode){
       case 1:
            if (resultCode == Activity.RESULT_OK) {
                  selectedImage = imageUri;
                  getContentResolver().notifyChange(selectedImage, null);
                  image= (ImageView) findViewById(R.id.imageview);
                  ContentResolver cr = getContentResolver();
                  Bitmap bitmap;
                  try {
                       bitmap = android.provider.MediaStore.Images.Media
                       .getBitmap(cr, selectedImage);
                       image.setImageBitmap(bitmap);
                       Toast.makeText(this, selectedImage.toString(),
                              Toast.LENGTH_LONG).show();
                  } catch (Exception e) {
                      Toast.makeText(this, "Failed to load", Toast.LENGTH_SHORT)
                              .show();
                      Log.e("Camera", e.toString());
                  }
                 }
             else 

         if(resultCode == Activity.RESULT_CANCELED) {
                    Toast.makeText(EditPhoto.this, "Picture could not be taken.", Toast.LENGTH_SHORT).show();
                }
       }
}

The problem is that all the photos that are taken are rotated with 90 degrees-horizontally aligned.

I've also put this into my manifest file:

 <activity android:name=".EditPhoto">
    android:screenOrientation="portrait"
    </activity>

But still with no result!So can anyone help me???

Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
adrian
  • 4,574
  • 17
  • 68
  • 119
  • 1
    The code you posted is for receiving the Image after it has been captured. I don't think you can simply put portrait or landscape. These relate more to the orientation of the view. But the camera can be mounted and rotated such a way that it requires the user to rotate the device to be able to view the world in what looks "normal" to them. So even if you say portrait the image could be projected another way. In later versions of the SDK there is a setRotation on the Camera (use have to hack up Parameters on old versions). There may be EXIF headers in the image to tell you the orientation. – Greg Giacovelli Jul 25 '11 at 08:08
  • So what's the solution!? – adrian Jul 25 '11 at 08:19
  • It's hard to tell without the capture code that you use. Could you post that? – Greg Giacovelli Jul 25 '11 at 15:15
  • I'm not using any capture code...this is all that I'm using for the camera...Can you give me a full example of capture code and code for receiving the image together??Thanks – adrian Jul 25 '11 at 17:55
  • Uh no thats' a large amount of code. I htought you actually implemented the other end of this interface (the one that listens for that intent). So what is edit photo? Does it just display a landscape image in portrait mode? I don't think the screen orientation will matter so much. What device is this? – Greg Giacovelli Jul 26 '11 at 05:22
  • But just a link....I don't wanna you to post it in here.Is Sony Ericsson!And it matters – adrian Jul 26 '11 at 06:27
  • @Greg let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/1823/discussion-between-george-and-greg) – adrian Jul 26 '11 at 06:27
  • @adrian can you get any solution for this? – CoronaPintu Dec 13 '13 at 09:55

2 Answers2

32

http://developer.android.com/reference/android/media/ExifInterface.html

http://developer.android.com/reference/android/media/ExifInterface.html#TAG_ORIENTATION

So if in

Activity.onActivityResult(data, request, result) {
 if (request == PHOTO_REQUEST && result == RESULT_OK) {
   ...
   Uri imageUri = ...
   File imageFile = new File(imageUri.toString());
   ExifInterface exif = new ExifInterface(imageFile.getAbsolutePath());
   int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
   int rotate = 0;
   switch(orientation) {
     case ExifInterface.ORIENTATION_ROTATE_270:
         rotate-=90;
     case ExifInterface.ORIENTATION_ROTATE_180:
         rotate-=90;
     case ExifInterface.ORIENTATION_ROTATE_90:
         rotate-=90;
   }
   Canvas canvas = new Canvas(bitmap);
   canvas.rotate(rotate);
 }

Does this help at all?


Just to add to Greg's great answer, here's a whole "category" to do the job:

public static int neededRotation(File ff)
        {
        try
            {

            ExifInterface exif = new ExifInterface(ff.getAbsolutePath());
            int orientation = exif.getAttributeInt(
               ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

            if (orientation == ExifInterface.ORIENTATION_ROTATE_270)
                { return 270; }
            if (orientation == ExifInterface.ORIENTATION_ROTATE_180)
                { return 180; }
            if (orientation == ExifInterface.ORIENTATION_ROTATE_90)
                { return 90; }
            return 0;

            } catch (FileNotFoundException e)
            {
            e.printStackTrace();
            } catch (IOException e)
            {
            e.printStackTrace();
            }
        return 0;
        }

you'd use it more or less like this ...

public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
    if (requestCode == REQUEST_IMAGE_CAPTURE) // && resultCode == RESULT_OK )
        {
        try
            {
            Bitmap cameraBmp = MediaStore.Images.Media.getBitmap(
                    State.mainActivity.getContentResolver(),
                    Uri.fromFile( Utils.tempFileForAnImage() )  );

            cameraBmp = ThumbnailUtils.extractThumbnail(cameraBmp, 320,320);
            // NOTE incredibly useful trick for cropping/resizing square
            // http://stackoverflow.com/a/17733530/294884

            Matrix m = new Matrix();
            m.postRotate( Utils.neededRotation(Utils.tempFileForAnImage()) );

            cameraBmp = Bitmap.createBitmap(cameraBmp,
                    0, 0, cameraBmp.getWidth(), cameraBmp.getHeight(),
                    m, true);

            yourImageView.setImageBitmap(cameraBmp);

            // to convert to bytes...
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            cameraBmp.compress(Bitmap.CompressFormat.JPEG, 75, baos);
            //or say cameraBmp.compress(Bitmap.CompressFormat.PNG, 0, baos);
            imageBytesRESULT = baos.toByteArray();

            } catch (FileNotFoundException e)
            {
            e.printStackTrace();
            } catch (IOException e)
            {
            e.printStackTrace();
            }

        return;
        }

    }

Hope it saves someone some typing in the future.

Fattie
  • 27,874
  • 70
  • 431
  • 719
Greg Giacovelli
  • 10,164
  • 2
  • 47
  • 64
3

The above answer is very thorough, but I found I had to do a little bit more in order for every case to work, especially if you're dealing with images from other sources such as the Gallery or Google Photos. Here's my DetermineOrientation method. I have a utility class where this is located so I have to pass in the Activity in order to use managedQuery(which btw is deprecated so use cautiously). The reason I have to use two methods is because, depending on the source of the image, ExifInterface will not work. For instance, if I take a camera photo, Exif works fine. However, if I'm also choosing images from the Gallery or Google Drive, Exif does not work and always returns 0. Hope this helps someone.

public static int DetermineOrientation(Activity activity, Uri fileUri)
{
    int orientation = -1;
    int rotate = 0;
    try {

        ExifInterface exif = new ExifInterface(fileUri.getPath());
        orientation = exif.getAttributeInt(
                ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
        rotate = 0;
        switch (orientation) {
            case ExifInterface.ORIENTATION_ROTATE_270:
                rotate = 270;
            case ExifInterface.ORIENTATION_ROTATE_180:
                rotate = 180;
            case ExifInterface.ORIENTATION_ROTATE_90:
                rotate = 90;
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    if(rotate == 0)
    {
        String[] orientationColumn = {MediaStore.Images.Media.ORIENTATION};
        Cursor cur = activity.managedQuery(fileUri, orientationColumn, null, null, null);
        orientation = -1;
        if (cur != null && cur.moveToFirst()) {
            orientation = cur.getInt(cur.getColumnIndex(orientationColumn[0]));
        }

        if(orientation != -1)
        {
            rotate = orientation;
        }
    }

    return rotate;
}
John Murphy
  • 905
  • 1
  • 10
  • 26