You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ExifInterface返回错误旋转角度,横转竖图片异常问题求助

问题分析与修改方案

已知你的exifOrientation值为6(对应ExifInterface.ORIENTATION_ROTATE_90),旋转结果异常的原因及修改方案如下:


问题根源

  • MediaStore.Images.Media.getBitmap自动处理Exif旋转:该API会读取图片Exif信息并自动旋转Bitmap,导致你手动再次旋转90度后,图片出现过度旋转/变形。
  • 旋转后未重置Exif方向标签:保存后的图片仍保留原Exif方向值,后续读取时会再次错误旋转。
  • exifToDegrees映射错误:原代码中ORIENTATION_TRANSVERSE和ORIENTATION_TRANSPOSE的角度映射不符合实际需求,会导致特殊方向的图片旋转异常。

修改后的完整代码

private fun checkRotation(savedUri: Uri) {
    val path = getRealPathFromURI(savedUri, this@NewStore) ?: return

    // 读取Exif方向信息
    val exif = ExifInterface(path)
    val exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED)
    val rotationDegrees = exifToDegrees(exifOrientation)

    // 解码Bitmap,避免MediaStore自动处理Exif旋转
    val options = BitmapFactory.Options().apply {
        inMutable = true
        inPreferredConfig = Bitmap.Config.ARGB_8888
    }
    val sourceBitmap = BitmapFactory.decodeFile(path, options) ?: return

    // 应用旋转矩阵
    val matrix = Matrix()
    if (rotationDegrees != 0) {
        matrix.postRotate(rotationDegrees.toFloat())
    }

    val rotatedBitmap = Bitmap.createBitmap(
        sourceBitmap,
        0,
        0,
        sourceBitmap.width,
        sourceBitmap.height,
        matrix,
        true
    )

    // 保存旋转后的Bitmap到文件
    FileOutputStream(path).use { outputStream ->
        rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
    }

    // 重置Exif的Orientation标签,避免后续读取错误
    val updatedExif = ExifInterface(path)
    updatedExif.setAttribute(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL.toString())
    updatedExif.saveAttributes()

    // 回收Bitmap释放内存
    sourceBitmap.recycle()
    rotatedBitmap.recycle()
}

private fun exifToDegrees(exifOrientation: Int): Int {
    return when (exifOrientation) {
        ExifInterface.ORIENTATION_ROTATE_90 -> 90
        ExifInterface.ORIENTATION_ROTATE_180 -> 180
        ExifInterface.ORIENTATION_ROTATE_270 -> 270
        ExifInterface.ORIENTATION_TRANSVERSE -> 270
        ExifInterface.ORIENTATION_TRANSPOSE -> 90
        else -> 0
    }
}

关键修改点说明

  • 替换Bitmap获取方式:用BitmapFactory.decodeFile替代MediaStore.Images.Media.getBitmap,避免自动处理Exif旋转,确保拿到图片原始像素方向。
  • 修正角度映射逻辑:调整ORIENTATION_TRANSVERSE和ORIENTATION_TRANSPOSE的角度映射,统一使用顺时针正角度,避免镜像+旋转导致的方向异常。
  • 重置Exif方向标签:保存图片后将Exif的方向设为ORIENTATION_NORMAL,确保后续读取图片时不会重复旋转。
  • 优化流管理:用use块自动关闭FileOutputStream,避免文件操作异常。

内容的提问来源于stack exchange,提问作者Captai-N

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 08:53:23