使用Odoo框架的Android平板拍照旋转异常问题排查求助
问题根源分析:Android端代码遗漏Exif方向处理,与Odoo框架无关
这个图片旋转异常的问题完全是Android端代码没有处理图片的Exif方向元数据导致的,和Odoo框架没有关系。原因很直观:
Android相机拍摄照片时,并不会直接旋转图片像素,而是把拍摄时的设备方向信息存在图片的Exif元数据里。但BitmapFactory.decodeByteArray()默认会忽略这些Exif信息,直接按图片原始像素的方向解码。只有当拍摄方向恰好和图片默认编码方向一致时(也就是你说的横屏Home键在右侧的场景),解码后的图片才会正常显示;其他拍摄方向下,因为Exif方向没有被应用,自然就会出现旋转/倒置的问题。
解决步骤:补充Exif读取与图片旋转逻辑
你需要在现有代码里加两个关键步骤:读取图片的Exif旋转角度,把解码后的Bitmap按该角度旋转,之后再做缩放处理。
1. 添加读取Exif旋转角度的方法
private static int getExifRotationAngle(Uri imageUri, ContentResolver contentResolver) { try { // 通过ContentResolver获取图片输入流,兼容不同Android版本 ExifInterface exif = new ExifInterface(contentResolver.openInputStream(imageUri)); int orientation = exif.getAttributeInt( ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL ); // 将Exif的方向常量转换为对应的旋转角度 switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: return 90; case ExifInterface.ORIENTATION_ROTATE_180: return 180; case ExifInterface.ORIENTATION_ROTATE_270: return 270; default: return 0; } } catch (IOException e) { Log.e(TAG, "Failed to read image Exif orientation", e); return 0; } }
2. 添加Bitmap旋转方法
private static Bitmap rotateBitmap(Bitmap bitmap, int rotationAngle) { if (rotationAngle == 0 || bitmap == null) { return bitmap; } Matrix matrix = new Matrix(); matrix.postRotate(rotationAngle); // 创建旋转后的Bitmap,保持图片质量 Bitmap rotatedBitmap = Bitmap.createBitmap( bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true ); // 回收原始Bitmap,避免内存泄漏 if (!bitmap.isRecycled()) { bitmap.recycle(); } return rotatedBitmap; }
3. 修改现有onActivityResult()中的图片处理流程
在解码Bitmap之后,先读取Exif角度并旋转图片,再进行缩放:
// 原解码代码 byte[] decodedImage = Base64.decode(imageBase64, Base64.DEFAULT); Bitmap bitmapImage = BitmapFactory.decodeByteArray(decodedImage, 0, decodedImage.length); // 新增:读取Exif旋转角度并旋转图片 Uri imageUri = Uri.parse(response.getString("file_uri")); int rotationAngle = getExifRotationAngle(imageUri, getContentResolver()); Bitmap rotatedBitmap = rotateBitmap(bitmapImage, rotationAngle); // 改用旋转后的Bitmap进行缩放 Bitmap scaledBitmap = scaleDown(rotatedBitmap, 1000, true); // 后续压缩、编码逻辑保持不变...
额外注意事项
- 如果你用的是Android 10及以上版本,确保已经申请了
READ_EXTERNAL_STORAGE权限(或者用MediaStore API访问图片,避免权限问题)。 - 处理完Bitmap后记得及时回收不再使用的实例,防止内存溢出。
内容的提问来源于stack exchange,提问作者Dario
相关产品推荐
相关产品推荐

