Android: Rotate and display image from file

爱⌒轻易说出口 提交于 2019-12-07 00:26:29

问题


I have a very simple layout with an ImageView. My application opens the camera, saves an image, and then displays the image in the ImageView with BitmapFactory.decodeFile. The only issue is that it's rotated. I understand that a) this is due to the phone's camera defaulting to landscape, so this needs to be handled in code and b) image processing must be done in a separate thread from the UI.

The Android training documentation seems to be geared toward loading images from resource id's instead of file paths. This just throws a wrench in things as I'm able to follow the tutorials up to a point but ultimately have trouble reconciling the differences.

I'm certainly new at this so if someone could just give me a high-level overview of what needs to be done to accomplish this, I'd really appreciate it. The following code is where I'm currently adding the bitmap to the ImageView. I assume that my call to the separate thread would go in onCreate?

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

    Bitmap bm = BitmapFactory.decodeFile(MainActivity.image_path);

    displayImageView = (ImageView) findViewById(R.id.myImageView);

    displayImageView.setImageBitmap(bm);
}

回答1:


Use ExifInterface for rotate

picturePath = getIntent().getStringExtra("path");
Bitmap bitmap = BitmapFactory.decodeFile(picturePath);
ExifInterface exif = new ExifInterface(picturePath);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);

Matrix matrix = new Matrix();
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
    matrix.postRotate(90);
    break;
case ExifInterface.ORIENTATION_ROTATE_180:
    matrix.postRotate(180);
    break;
case ExifInterface.ORIENTATION_ROTATE_270:
    matrix.postRotate(270);
    break;
default:
    break;
}

myImageView.setImageBitmap(bitmap);
bitmap.recycle();

Note : Here picturePath is selected Image's path from Gallery

  • tutorial



回答2:


I was able to get it working with the following approach. I think you could do this without the AsyncTask but it seems that best practice states you should perform image processing in a non-UI thread (please feel free to correct - I'm quite new at this).

An improvement which could be made to this would be to handle the scaling in a more granular way. inSampleSize is a great tool but it will only scale by powers of 2. Another improvement would be to initially only read the meta/EXIF data into bmOriginal as the only use of this variable is to retrieve the height and width.

ImageView XML - pretty much standard. android:layout_width/height set to fill_parent.

From the activity's java file -

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

    new ImageRotator().execute(MainActivity.image_path);
}

private class ImageRotator extends AsyncTask<String, Void, Bitmap>{
    protected Bitmap doInBackground(String... image_path){

        BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
        bitmapOptions.inSampleSize = 4;
        Bitmap bmOriginal = BitmapFactory.decodeFile(image_path[0], bitmapOptions);

        Matrix matrix = new Matrix();

        matrix.postRotate(90);

        bmOriginal = Bitmap.createBitmap(bmOriginal, 0, 0, bmOriginal.getWidth(), bmOriginal.getHeight(), matrix, true);

        return bmOriginal;
    }

    protected void onPostExecute(Bitmap result) {
        myImageView = (ImageView) findViewById(R.id.myImageView);

        myImageView.setImageBitmap(result);
    }
}

The scaling process was found here and there's a great explanation of AsyncTask's features here.

Thanks so much to all who responded and again - please feel free to let me know if this is way off base or even if there's just a better way to do this.




回答3:


Why bother to rotate the image. As you said "The ImageView itself is properly oriented. It's just that the image inside it is always displayed 90 degrees counter-clockwise. " , then just make the ImageView rotate 90 degrees clockwise, the image will display correctly.

    displayImageView.setRotation(90);



回答4:


You can rotate an image using a matrix or set the rotation in your xml. If you want more control however, you can check out this tutorial written for rotating images and saving to disk:

How to rotate an image in android

I hope that helped.



来源:https://stackoverflow.com/questions/25598027/android-rotate-and-display-image-from-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!