Bitmap压缩后高度未生效,图片旋转处理逻辑疑似异常
问题诊断与修复方案
看起来你的问题核心出在Exif图片方向的旋转逻辑上——你写的switch分支里有几个明显的错误,这直接导致添加旋转处理后,图片高度没有被正确压缩,功能出现异常。之前只做压缩没问题,就是因为旋转逻辑没介入,一旦加了错误的旋转处理,就打乱了压缩后的宽高预期。
具体错误点
- 当图片方向是
ORIENTATION_ROTATE_90时,你调用了matrix.postRotate(0)——等于完全没旋转,这和需求完全不符; - 当方向是
ORIENTATION_UNDEFINED时,你强制旋转90度,这不符合Exif方向的常规处理逻辑(未定义时应该保持原始方向); - 没有覆盖所有可能的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; }
额外优化建议
- 异常日志不能丢:原代码的catch块是空的,一旦出现异常你完全不知道问题出在哪,加上
e.printStackTrace()能帮你快速定位错误; - 内存回收:生成旋转后的Bitmap后,记得回收原始的
compressedImage,避免Bitmap占用过多内存导致OOM; - 可选:先旋转再压缩:如果你的业务场景允许,先根据Exif方向旋转原始图片,再进行压缩,这样能避免压缩后旋转带来的宽高比例偏差,不过这取决于你具体的需求。
内容的提问来源于stack exchange,提问作者rishi lara
相关产品推荐
相关产品推荐

