Android:如何在设置图像视图时检测从图库中选取的图像方向(纵向或横向)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12726860/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 11:33:48  来源:igfitidea点击:

Android : How to detect the image orientation (portrait or landscape) picked from gallery while setting on an imageview?

androidandroid-imageviewandroid-gallery

提问by sarabhai05

I am setting an image on the imageview picked from the gallery(camera album). If the picked image has landscape orientation, it displays perfectly but if the image in in portrait mode(i.e the image was clicked in portrait mode) it is displaying the image with a 90 degree rotation. Now I am trying to find out the orientation just before setting on imageview, but all the images are giving same orientation and same width-height. Here is my code :

我正在从图库(相册)中选取的图像视图上设置图像。如果选择的图像具有横向方向,则显示完美,但如果图像处于纵向模式(即在纵向模式下单击图像),则它会显示旋转 90 度的图像。现在我试图在设置 imageview 之前找出方向,但所有图像都给出相同的方向和相同的宽高。这是我的代码:

Uri selectedImage = intent.getData();
if (selectedImage != null) {
    Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage);

    int str = new ExifInterface(selectedImage.getPath()).getAttributeInt("Orientation", 1000);
    Toast.makeText(this, "value:" + str, Toast.LENGTH_LONG).show();
    Toast.makeText(this, "width:" + bitmap.getWidth() + "height:" + bitmap.getHeight(), Toast.LENGTH_LONG).show();

portrait modelandscape mode

纵向模式横向模式

回答by Deepak

Use ExifInterfacefor rotate image. Use this method for get correct value to be rotate captured image from camera.

使用ExifInterface用于旋转图像。使用此方法获取正确值以从相机旋转捕获的图像。

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;
}

And put this code in Activity result method and get value to rotate image...

并将此代码放在 Activity 结果方法中并获取旋转图像的值...

String selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};

Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();

int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
filePath = cursor.getString(columnIndex);
cursor.close();

int rotateImage = getCameraPhotoOrientation(MyActivity.this, selectedImage, filePath);

Hope this helps..

希望这可以帮助..

回答by sarabhai05

This is also working for me:

这也对我有用:

String[] orientationColumn = {MediaStore.Images.Media.ORIENTATION};
Cursor cur = getContentResolver().query(imageUri, orientationColumn, null, null, null);
int orientation = -1;
if (cur != null && cur.moveToFirst()) {
    orientation = cur.getInt(cur.getColumnIndex(orientationColumn[0]));
}
Matrix matrix = new Matrix();
matrix.postRotate(orientation);

回答by ultimate

                      if(bm.getWidth() > bm.getHeight())
                        {
                            Bitmap bMapRotate=null;
                            Matrix mat=new Matrix();
                            mat.postRotate(90);
                        bMapRotate = Bitmap.createBitmap(bm, 0, 0,bm.getWidth(),bm.getHeight(), mat, true);
                        bm.recycle();
                        bm=null;
                        imageDisplayView.setImageBitmap(bMapRotate);
                        }else
                        imageDisplayView.setImageBitmap(bm);

回答by Andrew Moreau

Here is a great solution I came across for this: >https://stackoverflow.com/a/34241250/8033090

这是我遇到的一个很好的解决方案:> https://stackoverflow.com/a/34241250/8033090

One line solution:

一行解决方案:

Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);

or

或者

Picasso.with(context).load("file:" + photoPath).into(imageView);

This will autodetect rotation and place image in correct orientation

这将自动检测旋转并将图像放置在正确的方向

Picasso is a very powerful library for handling images in your app includes: Complex image transformations with minimal memory use. It can take a second to load but I just put some text behind the image view that says "Loading image" and when the image loads it covers the text.

Picasso 是一个非常强大的库,用于在您的应用程序中处理图像,包括: 以最少的内存使用复杂的图像转换。加载可能需要一秒钟,但我只是在图像视图后面放了一些文字,上面写着“正在加载图像”,当图像加载时,它会覆盖文本。

回答by Yunus Güng?r

Using kotlin and considering the change in uri and in exif in new android versions:

使用 kotlin 并考虑新 android 版本中 uri 和 exif 的变化:

 var exif: ExifInterface? = null;
 try {
    when (Build.VERSION.SDK_INT) {
        in Int.MIN_VALUE..24 -> exif = ExifInterface(imageUri.path)
        else -> exif = ExifInterface(getContentResolver().openInputStream(data.extras.get("data")))
     }
 } catch (e: IOException) {
     e.printStackTrace();
 }
 val orientation = exif?.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
 bmp = rotateBitmap(bmp, orientation ?: ExifInterface.ORIENTATION_NORMAL)

And the rotateBitmap function is:

而rotateBitmap函数是:

un rotateBitmap(bitmap: Bitmap, orientation: Int): Bitmap {
val matrix = Matrix()
when (orientation) {
    ExifInterface.ORIENTATION_NORMAL -> return bitmap
    ExifInterface.ORIENTATION_FLIP_HORIZONTAL -> matrix.setScale(-1f, 1f)
    ExifInterface.ORIENTATION_ROTATE_180 -> matrix.setRotate(180f)
    ExifInterface.ORIENTATION_FLIP_VERTICAL -> {
        matrix.setRotate(180f)
        matrix.postScale(-1f, 1f)
    }
    ExifInterface.ORIENTATION_TRANSPOSE -> {
        matrix.setRotate(90f)
        matrix.postScale(-1f, 1f)
    }
    ExifInterface.ORIENTATION_ROTATE_90 -> matrix.setRotate(90f)
    ExifInterface.ORIENTATION_TRANSVERSE -> {
        matrix.setRotate(-90f)
        matrix.postScale(-1f, 1f)
    }
    ExifInterface.ORIENTATION_ROTATE_270 -> matrix.setRotate(-90f)
    else -> return bitmap
}
try {
    val bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
    bitmap.recycle()
    return bmRotated
} catch (e: OutOfMemoryError) {
    e.printStackTrace()
    return null
}

}

}

回答by ?lker El?ora

Using the EXIF information is not reliable on some android devices. (ExifInterface orientation return always 0)

在某些安卓设备上使用 EXIF 信息是不可靠的。(ExifInterface 方向始终返回 0)

This is working for me:

这对我有用:

Rotate bitmap

旋转位图

public static Bitmap rotateBitmap(Context context, Uri photoUri, Bitmap bitmap) 
{
    int orientation = getOrientation(context, photoUri);
    if (orientation <= 0) {
        return bitmap;
    }

    Matrix matrix = new Matrix();
    matrix.postRotate(orientation);
    bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
    return bitmap;
}

Get orientation from MediaStore

从 MediaStore 获取方向

private static int getOrientation(Context context, Uri photoUri) 
{
    Cursor cursor = context.getContentResolver().query(photoUri,
            new String[]{MediaStore.Images.ImageColumns.ORIENTATION}, null, null, null);

    if (cursor.getCount() != 1) {
        cursor.close();
        return -1;
    }

    cursor.moveToFirst();
    int orientation = cursor.getInt(0);
    cursor.close();
    cursor = null;
    return orientation;
}

回答by lucasddaniel

Another solution is to use the ExifInterface from support library: ExifInterface from support library

另一种解决方案是使用支持库中的 ExifInterface:支持库中的 ExifInterface

回答by ilmetu

This work for me :

这对我有用:

private String getOrientation(Uri uri){
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    String orientation = "landscape";
    try{
        String image = new File(uri.getPath()).getAbsolutePath();
        BitmapFactory.decodeFile(image, options);
        int imageHeight = options.outHeight;
        int imageWidth = options.outWidth;
        if (imageHeight > imageWidth){
            orientation = "portrait";
        }
    }catch (Exception e){
        //Do nothing
    }
    return orientation;
}