我正在捕捉图像并将其设置为图像视图。

public void captureImage() {

    Intent intentCamera = new Intent("android.media.action.IMAGE_CAPTURE");
    File filePhoto = new File(Environment.getExternalStorageDirectory(), "Pic.jpg");
    imageUri = Uri.fromFile(filePhoto);
    MyApplicationGlobal.imageUri = imageUri.getPath();
    intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
    startActivityForResult(intentCamera, TAKE_PICTURE);
}

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

    if (resultCode == RESULT_OK && requestCode == TAKE_PICTURE) {

        if (intentFromCamera != null) {
            Bundle extras = intentFromCamera.getExtras();
            if (extras.containsKey("data")) {
                bitmap = (Bitmap) extras.get("data");
            }
            else {
                bitmap = getBitmapFromUri();
            }
        }
        else {
            bitmap = getBitmapFromUri();
        }
        // imageView.setImageBitmap(bitmap);
        imageView.setImageURI(imageUri);
    }
    else {
    }
}

public Bitmap getBitmapFromUri() {

    getContentResolver().notifyChange(imageUri, null);
    ContentResolver cr = getContentResolver();
    Bitmap bitmap;

    try {
        bitmap = android.provider.MediaStore.Images.Media.getBitmap(cr, imageUri);
        return bitmap;
    }
    catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

但问题是,某些设备上的图像每次旋转时。例如,在三星设备上,它工作得很好,但在索尼Xperia上,图像旋转了90度,在东芝Thrive(平板电脑)上旋转了180度。


当前回答

我根据@Jason Robinson的回答创建了一个Kotlin扩展函数,简化了Kotlin开发人员的操作。我希望这能有所帮助。

fun Bitmap.fixRotation(uri: Uri): Bitmap? {

    val ei = ExifInterface(uri.path)

    val orientation: Int = ei.getAttributeInt(
        ExifInterface.TAG_ORIENTATION,
        ExifInterface.ORIENTATION_UNDEFINED
    )

    return when (orientation) {
        ExifInterface.ORIENTATION_ROTATE_90 -> rotateImage( 90f)
        ExifInterface.ORIENTATION_ROTATE_180 -> rotateImage( 180f)
        ExifInterface.ORIENTATION_ROTATE_270 -> rotateImage( 270f)
        ExifInterface.ORIENTATION_NORMAL -> this
        else -> this
    }
}

fun Bitmap.rotateImage(angle: Float): Bitmap? {
    val matrix = Matrix()
    matrix.postRotate(angle)
    return Bitmap.createBitmap(
        this, 0, 0, width, height,
        matrix, true
    )
}

其他回答

这可能是不言而喻的,但请始终记住,您可以在服务器上处理其中一些映像处理问题。我使用类似于这个线程中包含的响应来处理图像的即时显示。然而,我的应用程序要求图像存储在服务器上(这可能是一个常见的要求,如果你希望图像在用户切换手机时保持不变)。

关于这个主题的许多讨论中包含的解决方案没有讨论EXIF数据缺乏持久性的问题,这种数据无法在位图的图像压缩中幸存下来,这意味着您需要在服务器每次加载图像时旋转图像。或者,您可以将EXIF方向数据发送到服务器,然后根据需要旋转图像。

对我来说,在服务器上创建一个永久的解决方案更容易,因为我不必担心Android的秘密文件路径。

大多数手机摄像头都是横拍的,也就是说如果你用竖拍,拍出来的照片会旋转90度。在这种情况下,相机软件应该填充Exif数据,以显示照片的方向。

请注意,下面的解决方案取决于填充Exif数据的相机软件/设备制造商,因此它在大多数情况下都可以工作,但它不是100%可靠的解决方案。

ExifInterface ei = new ExifInterface(photoPath);
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                                     ExifInterface.ORIENTATION_UNDEFINED);

Bitmap rotatedBitmap = null;
switch(orientation) {

    case ExifInterface.ORIENTATION_ROTATE_90:
        rotatedBitmap = rotateImage(bitmap, 90);
        break;

    case ExifInterface.ORIENTATION_ROTATE_180:
        rotatedBitmap = rotateImage(bitmap, 180);
        break;

    case ExifInterface.ORIENTATION_ROTATE_270:
        rotatedBitmap = rotateImage(bitmap, 270);
        break;

    case ExifInterface.ORIENTATION_NORMAL:
    default:
        rotatedBitmap = bitmap;
}

下面是rotateImage方法:

public static Bitmap rotateImage(Bitmap source, float angle) {
    Matrix matrix = new Matrix();
    matrix.postRotate(angle);
    return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(),
                               matrix, true);
}

如果有人在Android 4.4 (KitKat)上使用ExifInterface获得方向时遇到问题,这可能是因为从URI获得了错误的路径。在堆栈溢出问题中看到一个解决方案,从URI获得真正的路径,Android奇巧新的存储访问框架

Jason Robinson和Sami Eltamawy的回答非常棒。

只是为了完成该方法的改进,您应该使用compat ExifInterface。

com.android.support: exifinterface: $ {lastLibVersion}

你将能够实例化ExifInterface(pior API <24)与InputStream(从ContentResolver)而不是uri路径避免“文件未找到异常”

https://android-developers.googleblog.com/2016/12/introducing-the-exifinterface-support-library.html

我用了另一种方法。你所要做的就是检查宽度是否大于高度

Matrix rotationMatrix = new Matrix();
if(finalBitmap.getWidth() >= finalBitmap.getHeight()){
    rotationMatrix.setRotate(-90);
}else{
    rotationMatrix.setRotate(0);
}

Bitmap rotatedBitmap = Bitmap.createBitmap(finalBitmap,0,0,finalBitmap.getWidth(),finalBitmap.getHeight(),rotationMatrix,true);