Android中OpenGL可正常显示图库图片但无法展示相机拍摄图片求助
问题修复方案
1. 补全相机调用的URI权限授予
当前相机调用逻辑没有给目标相机应用授予URI写入权限,导致相机无法将拍摄的图片正常写入指定的文件路径,最终加载出的Bitmap为空或损坏。在构造相机Intent时添加权限标记即可:
Intent takePic = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (takePic.resolveActivity(getPackageManager()) != null) { File imagen = controler.createPhotoFile(getExternalFilesDir(Environment.DIRECTORY_PICTURES)); if (imagen != null) { photoUri = FileProvider.getUriForFile(this, "my.fileprovider", imagen); // 新增权限授予 takePic.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); takePic.putExtra(MediaStore.EXTRA_OUTPUT, photoUri); startActivityForResult(takePic, 1); } }
2. 优化Bitmap加载逻辑,处理EXIF旋转信息
相机拍摄的图片默认会携带EXIF旋转标记,系统图库加载时会自动处理旋转,但MediaStore.Images.Media.getBitmap不会识别该标记,导致加载出的Bitmap方向错误,看起来像渲染异常。同时该方法存在兼容性问题,推荐改用流加载方式,同时增加旋转处理逻辑:
首先添加两个工具方法:
// 读取图片EXIF中的旋转角度 private int getBitmapRotateAngle(Uri uri) { int rotate = 0; try { InputStream input = getContentResolver().openInputStream(uri); ExifInterface exifInterface = new ExifInterface(input); int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: rotate = 90; break; case ExifInterface.ORIENTATION_ROTATE_180: rotate = 180; break; case ExifInterface.ORIENTATION_ROTATE_270: rotate = 270; break; } } catch (Exception e) { e.printStackTrace(); } return rotate; } // 旋转Bitmap到正确角度 private Bitmap rotateBitmap(Bitmap bitmap, int angle) { if (angle == 0) return bitmap; Matrix matrix = new Matrix(); matrix.postRotate(angle); return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); }
修改sendImagenPanel方法:
private void sendImagenPanel(Uri uri) { Bitmap bitmap = null; try { // 改用流加载,兼容性更好 InputStream inputStream = getContentResolver().openInputStream(uri); bitmap = BitmapFactory.decodeStream(inputStream); // 处理旋转 int rotateAngle = getBitmapRotateAngle(uri); bitmap = rotateBitmap(bitmap, rotateAngle); } catch (IOException e) { e.printStackTrace(); } // 增加空校验,避免后续逻辑崩溃 if (bitmap == null) return; final Bitmap imagen = controler.getCroppedBitmap(controler.scaledBitmap(bitmap, 256)); final CasillaOG casilla = ((GLSurfacePanel) gLViewPanel).getRendererPanel().getCuboSelected(); gLViewPanel.queueEvent(new Runnable() { @Override public void run() { casilla.loadNewTexture(imagen); casilla.setImagen(imagen); } }); gLViewPanel.requestRender(); }
3. 额外校验配置
- 确认AndroidManifest.xml中FileProvider的
authorities属性和代码中的my.fileprovider完全一致,且provider的路径配置包含了你使用的getExternalFilesDir(Environment.DIRECTORY_PICTURES)目录 - 确认App已经申请了对应系统版本所需的相机、存储权限,Android13+需要申请
CAMERA权限,Android10以下需要申请WRITE_EXTERNAL_STORAGE权限 - 你当前图库调用的Intent中
setType参数不完整,建议修改为intent.setType("image/*");,避免部分机型无法正常筛选图片
内容的提问来源于stack exchange,提问作者Bocho
相关产品推荐
相关产品推荐

