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

Bitmap压缩后高度未生效,图片旋转处理逻辑疑似异常

问题诊断与修复方案

看起来你的问题核心出在Exif图片方向的旋转逻辑上——你写的switch分支里有几个明显的错误,这直接导致添加旋转处理后,图片高度没有被正确压缩,功能出现异常。之前只做压缩没问题,就是因为旋转逻辑没介入,一旦加了错误的旋转处理,就打乱了压缩后的宽高预期。

具体错误点

  1. 当图片方向是ORIENTATION_ROTATE_90时,你调用了matrix.postRotate(0)——等于完全没旋转,这和需求完全不符;
  2. 当方向是ORIENTATION_UNDEFINED时,你强制旋转90度,这不符合Exif方向的常规处理逻辑(未定义时应该保持原始方向);
  3. 没有覆盖所有可能的Exif方向分支,比如翻转类的方向,虽然你可能没遇到,但完善分支能避免后续潜在问题。

修复后的完整代码

private Bitmap getBitmapScaled(String dirname, String filename) {
    Bitmap compressedImage = null;
    Bitmap compressedImage1 = null;
    try {
        Matrix matrix = new Matrix();
        File file = getMeterFilePath(dirname, filename);
        ExifInterface exif = new ExifInterface(file.getAbsolutePath());
        int orientation = exif.getAttributeInt(
                ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
        Log.d("1111111111111", "" + orientation);

        // 修正Exif方向对应的旋转/翻转逻辑
        switch (orientation) {
            case ExifInterface.ORIENTATION_ROTATE_270:
                matrix.postRotate(270);
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                matrix.postRotate(180);
                break;
            case ExifInterface.ORIENTATION_ROTATE_90:
                matrix.postRotate(90); // 这里修正为正确的90度旋转
                break;
            case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
                matrix.postScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_FLIP_VERTICAL:
                matrix.postScale(1, -1);
                break;
            case ExifInterface.ORIENTATION_TRANSPOSE:
                matrix.postRotate(90);
                matrix.postScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_TRANSVERSE:
                matrix.postRotate(270);
                matrix.postScale(-1, 1);
                break;
            // 正常方向和未定义情况,保持原始状态
            case ExifInterface.ORIENTATION_NORMAL:
            case ExifInterface.ORIENTATION_UNDEFINED:
            default:
                // 无需旋转/翻转
                break;
        }

        // 压缩图片到指定宽高
        compressedImage = new Compressor.Builder(mContext)
                .setMaxWidth(AppConstants.IMAGE_WIDTH)
                .setMaxHeight(AppConstants.IMAGE_HEIGHT)
                .setQuality(1)
                .setCompressFormat(Bitmap.CompressFormat.JPEG)
                .build()
                .compressToBitmap(file);

        // 应用旋转矩阵并添加水印
        if (compressedImage != null) {
            compressedImage1 = Bitmap.createBitmap(compressedImage, 0, 0,
                    compressedImage.getWidth(), compressedImage.getHeight(), matrix, true);
            // 回收原始压缩Bitmap,避免内存泄漏
            compressedImage.recycle();
            
            if (compressedImage1 != null) {
                compressedImage1 = CommonUtils.addWaterMarkDate(compressedImage1, CommonUtils.getCurrentDateTime());
            }
        }
    } catch (Exception e) {
        e.printStackTrace(); // 建议保留异常日志,方便后续排查问题
    }
    return compressedImage1;
}

额外优化建议

  1. 异常日志不能丢:原代码的catch块是空的,一旦出现异常你完全不知道问题出在哪,加上e.printStackTrace()能帮你快速定位错误;
  2. 内存回收:生成旋转后的Bitmap后,记得回收原始的compressedImage,避免Bitmap占用过多内存导致OOM;
  3. 可选:先旋转再压缩:如果你的业务场景允许,先根据Exif方向旋转原始图片,再进行压缩,这样能避免压缩后旋转带来的宽高比例偏差,不过这取决于你具体的需求。

内容的提问来源于stack exchange,提问作者rishi lara

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 00:27:41