Photo taken by camera returns reversed

Asked

Viewed 2,476 times

5

Is there any way not to invert the photo after updating it in an Imageview? For example, the application I’m developing accesses the device’s camera and after taking the photo, updates Imageview with the photo reversed. I wanted to leave it the same way that is viewed in the mobile photo library.

In my code, I am already able to change the image size after updating in Imageview.

Code

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MainActivity extends ActionBarActivity {

static final int REQUEST_IMAGE_CAPTURE = 1;

String mCurrentPhotoPath;
ImageView imageCapturedView;

private Bitmap bitmap;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    imageCapturedView = (ImageView) findViewById(R.id.imageView);

    imageCapturedView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            abrirCamera();
        }

    });
}

public void abrirCamera(){
    Intent captureImageIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if(captureImageIntent.resolveActivity(getPackageManager())!=null) {
        File photoFile=null;

        try {
            photoFile = createImageFile();
        } catch(IOException e){

        }

        if(photoFile != null) {
            captureImageIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
            startActivityForResult(captureImageIntent, REQUEST_IMAGE_CAPTURE);
        }
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if(requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
        //Bundle extras = data.getExtras();
        //Bitmap imageBitmap = (Bitmap) extras.get("data");
        //imageCapturedView.setImageBitmap(imageBitmap);
        galleryAddPic();
        setPic();
    }
}

private File createImageFile() throws IOException {
    String TimeStamp = new SimpleDateFormat("yyyyMMDdd_HHmmss").format(new Date());
    String ImageFile = "JPEG_" + TimeStamp + "_";
    File StorageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);

    File image = File.createTempFile(ImageFile, ".jpg", StorageDir);

    mCurrentPhotoPath = image.getAbsolutePath();

    return image;

}

private void galleryAddPic()
{
    /*Intent mediaScan = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
    File f= new File(mCurrentPhotoPath);
    Uri contentUri = Uri.fromFile(f);
    mediaScan.setData(contentUri);
    this.sendBroadcast(mediaScan);*/
}

private void setPic() throws ArithmeticException{
    int scaleFactor;
    Bitmap bitmap;
    // Get the dimensions of the View
    int targetW = imageCapturedView.getWidth();
    int targetH = imageCapturedView.getHeight();

    // Get the dimensions of the bitmap
    BitmapFactory.Options bmOptions = new BitmapFactory.Options();
    bmOptions.inJustDecodeBounds = true;
    //bmOptions.inSampleSize = 4;
    BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
    int photoW = bmOptions.outWidth;
    int photoH = bmOptions.outHeight;

    if(targetH == 0) targetH = 1;
    if(targetW == 0) targetW = 1;

    // Determine how much to scale down the image
    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 = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);

    Toast.makeText(getApplicationContext(), mCurrentPhotoPath, Toast.LENGTH_LONG).show();
    imageCapturedView.setImageBitmap(bitmap);
}

/* ----------------------------------- */

public boolean onCreateOptionsMenu(Menu menu) {
    // adiciona itens para a barra de ação, se ela estiver presente.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;

}
}

1 answer

3

Depending on the cell phone camera drive this rotates the photo before recording or stores the value of the rotation in the TAG_ORIENTATION.

So, in order for our program to display the photo correctly, we have to read the EXIF associated with the photo and run it according to TAG_ORIENTATION .

Code to get rotation recorded in EXIF:

ExifInterface exif = new ExifInterface(filename);  
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);  

Code to rotate the photo:

Bitmap bmRotated = rotateBitmap(bitmap, orientation);  

Method to run bitmap:

public static Bitmap rotateBitmap(Bitmap bitmap, int orientation) {

    try{
        Matrix matrix = new Matrix();
        switch (orientation) {
            case ExifInterface.ORIENTATION_NORMAL:
                return bitmap;
            case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
                matrix.setScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                matrix.setRotate(180);
                break;
            case ExifInterface.ORIENTATION_FLIP_VERTICAL:
                matrix.setRotate(180);
                matrix.postScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_TRANSPOSE:
                matrix.setRotate(90);
                matrix.postScale(-1, 1);
                break;
           case ExifInterface.ORIENTATION_ROTATE_90:
               matrix.setRotate(90);
               break;
           case ExifInterface.ORIENTATION_TRANSVERSE:
               matrix.setRotate(-90);
               matrix.postScale(-1, 1);
               break;
           case ExifInterface.ORIENTATION_ROTATE_270:
               matrix.setRotate(-90);
               break;
           default:
               return bitmap;
        }
        try {
            Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
            bitmap.recycle();
            return bmRotated;
        }
        catch (OutOfMemoryError e) {
            e.printStackTrace();
            return null;
        }
    }
    catch (IOException e) {
        e.printStackTrace();
        return null;
    }
    return bitmap;
}
  • Your post was very helpful. I have just one question. I took this same application to access the photo library of the phone, instead of opening the camera. After accessing the photos, I can select any photo and update the Imageview I put in my app. The point is that I can select to update any photo except the ones that were taken by the camera. I suspect this is happening because the photo is being loaded in a larger size than the display. If I resize the photo via code will I be able to handle the photos taken by the camera? @ramaral

  • I don’t understand what you mean:"except those taken by the camera"

  • When I enter the photo gallery of my mobile phone, I have several directories containing images, for example, photos I received on Whatsapp, instagram photos, facebook etc. In the directory that are the photos I took from my mobile phone, when I choose them, they do not appear in my app. The other photos I mentioned appear. @ramaral

  • I think you’d better post a new question exposing this problem, include the code you’re using.

  • I posted a new query with the code on [http://answall.com/questions/47056/resize-imagens-da-c%C3%A2mera-android-app] @ramaral

Browser other questions tagged

You are not signed in. Login or sign up in order to post.