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

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度。


当前回答

这是Xamarin。Android版本:

来自@Jason Robinson的回答:

Bitmap rotate(Bitmap bitmap, int angle)
{
    var matrix = new Matrix();
    matrix.PostRotate(angle);

    return Bitmap.CreateBitmap(bitmap, 0, 0, bitmap.Width, bitmap.Height, matrix, true);
}

Bitmap rotateIfRequired(Bitmap bitmap, string imagePath)
{
    var ei = new ExifInterface(imagePath);
    var orientation = ei.GetAttributeInt(ExifInterface.TagOrientation, (int)Android.Media.Orientation.Undefined);

    switch (orientation)
    {
        case (int)Android.Media.Orientation.Rotate90: return rotate(bitmap, 90);
        case (int)Android.Media.Orientation.Rotate180: return rotate(bitmap, 180);
        case (int)Android.Media.Orientation.Rotate270: return rotate(bitmap, 270);
        default: return bitmap;
    }
}

然后calculateInSampleSize方法:

int calculateInSampleSize(BitmapFactory.Options options, int reqW, int reqH)
{
    float h = options.OutHeight;
    float w = options.OutWidth;
    var inSampleSize = 1;

    if (h > reqH || w > reqW)
    {
        if (reqH == 0) inSampleSize = (int)Math.Floor(w / reqW);
        else if (reqW == 0) inSampleSize = (int)Math.Floor(h / reqH);
        else
        {
            var hRatio = (int)Math.Floor(h / reqH);
            var wRatio = (int)Math.Floor(w / reqW);
            inSampleSize = false ? Math.Max(hRatio, wRatio) : Math.Min(hRatio, wRatio);
        }
    }

    return inSampleSize;
}

来自@Sami Eltamawy的回答:

Bitmap handleSamplingAndRotationBitmap(string imagePath)
{
    var maxHeight = 1024;
    var maxWidth = 1024;

    var options = new BitmapFactory.Options();
    options.InJustDecodeBounds = true;
    BitmapFactory.DecodeFile(imagePath, options);

    options.InSampleSize = calculateInSampleSize(options, maxWidth, maxHeight);

    options.InJustDecodeBounds = false;

    var bitmap = BitmapFactory.DecodeFile(imagePath, options);

    bitmap = rotateIfRequired(bitmap, imagePath);

    return bitmap;
}

其他回答

下面的代码与我一起工作,它从fileUri获得位图,并在需要时进行旋转固定:

    private fun getCapturedImage(selectedPhotoUri: Uri): Bitmap {
        val bitmap = when {
            Build.VERSION.SDK_INT < 28 -> MediaStore.Images.Media.getBitmap(
                this.contentResolver,
                selectedPhotoUri
            )
            else -> {
                val source = ImageDecoder.createSource(this.contentResolver, selectedPhotoUri)
                ImageDecoder.decodeBitmap(source)
            }
        }

        // If the image is rotated, fix it
        return when (ExifInterface(contentResolver.run { openInputStream(selectedPhotoUri) }).getAttributeInt(
            ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED)) {
            ExifInterface.ORIENTATION_ROTATE_90 ->
                Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, Matrix().apply {
                    postRotate(90F) }, true)
            ExifInterface.ORIENTATION_ROTATE_180 ->
                Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, Matrix().apply {
                    postRotate(180F) }, true)
            ExifInterface.ORIENTATION_ROTATE_270 ->
                Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, Matrix().apply {
                    postRotate(270F) }, true)
            else -> bitmap
        } 
    }

使用Glide库对我很有用。旋转是自动的。

Bitmap bitmap = Glide.with(myContext).asBitmap().load(imageFilePath).submit(SIZE_ORIGINAL, SIZE_ORIGINAL).get();

然后将该位图保存为JPEG格式的文件。

如果你只是想加载到一个ImageView而不是保存到一个文件:

Glide.with(myContext).load(imageFilePath).into(myImageView)

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

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

如果你用的是Fresco,你可以用这个

final ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(uri)
.setRotationOptions(RotationOptions.autoRotate())
.build();

mSimpleDraweeView.setController(
Fresco.newDraweeControllerBuilder()
    .setImageRequest(imageRequest)
    .build());

这将根据Exif数据自动旋转图像。

来源:https://frescolib.org/docs/rotation.html