Значение тега ориентации EXIF ​​всегда 0 для изображения, сделанного с помощью приложения для портретов с вертикальной камерой

У меня есть приложение для камеры в портретном режиме, которое снимает изображения с передней и задней камер. Я сохраняю изображение на своей SD-карте и пытаюсь найти соответствующее значение exif, которое всегда дает 0. Но я получаю ожидаемую ориентацию exif значение для других изображений, хранящихся на устройстве (например, загруженные изображения).

Как я могу это исправить ? Может кто-нибудь мне помочь ?

Вот код, используемый для сохранения изображения и поиска ориентации

PictureCallback myPictureCallback_JPG = new PictureCallback() { @Override public void onPictureTaken(byte[] arg0, Camera arg1) { // TODO Auto-generated method stub try { File APP_FILE_PATH = new File(Environment.getExternalStorageDirectory() .getPath() + "/Myapp/"); if (!APP_FILE_PATH.exists()) { APP_FILE_PATH.mkdirs(); } File file = new File(APP_FILE_PATH, "image.jpg"); FileOutputStream fos = new FileOutputStream(file); fos.write(arg0); fos.close(); imageFileUri=Uri.fromfile(file); getApplicationContext().getContentResolver().notifyChange( imageFileUri, null); sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory()))); ExifInterface exif = new ExifInterface(file.getAbsolutePath()); int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); } catch (Exception e) { } } }; 

Ниже приведен код для создания и изменения функций

 @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { List sizes = parameters.getSupportedPreviewSizes(); Size optimalSize = getOptimalPreviewSize(sizes, width, height); parameters.setPreviewSize(optimalSize.width, optimalSize.height); camera.setParameters(parameters); camera.startPreview(); startPreview(); } @Override public void surfaceCreated(SurfaceHolder holder) { try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { Camera.CameraInfo info=new Camera.CameraInfo(); for (int i=0; i = 8) { int degrees = 0; switch (rotation) { case Surface.ROTATION_0: degrees = 0; break; case Surface.ROTATION_90: degrees = 90; break; case Surface.ROTATION_180: degrees = 180; break; case Surface.ROTATION_270: degrees = 270; break; } int result; if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = (info.orientation + degrees) % 360; result = (360 - result) % 360; } else { // back-facing result = (info.orientation - degrees + 360) % 360; } camera.setDisplayOrientation(result); } else { parameters.set("orientation", "portrait"); } camera.setParameters(parameters); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private Size getOptimalPreviewSize(List sizes, int w, int h) { final double ASPECT_TOLERANCE = 0.1; double targetRatio = (double) w / h; if (sizes == null) return null; Size optimalSize = null; double minDiff = Double.MAX_VALUE; int targetHeight = h; for (Size size : sizes) { double ratio = (double) size.width / size.height; if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } if (optimalSize == null) { minDiff = Double.MAX_VALUE; for (Size size : sizes) { if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } } return optimalSize; } 

Я также столкнулся с такой же проблемой в устройствах Samsung, позже я реализовал ExifInterface и успешно решил.

В любом режиме изображения будут сняты, он всегда будет храниться только в портретном режиме, а также при возврате изображения в портретном режиме. ниже кода, который я использовал для достижения своей цели, я реализовал в задней камере, не уверен, что с камеры.

Camera Intent @

 Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri); startActivityForResult(intent, 1212); 

onActivityResult @

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 1212) { sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory()))); Bitmap bitmap; //bitmap=GlobalMethods.decodeSampledBitmapFromResource(_path, 80, 80); bitmap=GlobalMethods.decodeFile(_path); if (bitmap == null) { imgMed.setImageBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.add_photo)); } else { imgMed.setImageBitmap(bitmap); imgMed.setScaleType(ScaleType.FIT_XY); } } } 

decodeFile @

  public static Bitmap decodeFile(String path) { int orientation; try { if(path==null){ return null; } // decode image size BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; // Find the correct scale value. It should be the power of 2. final int REQUIRED_SIZE = 70; int width_tmp = o.outWidth, height_tmp = o.outHeight; int scale = 4; while (true) { if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE) break; width_tmp /= 2; height_tmp /= 2; scale++; } // decode with inSampleSize BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize=scale; Bitmap bm = BitmapFactory.decodeFile(path,o2); Bitmap bitmap = bm; ExifInterface exif = new ExifInterface(path); orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1); Log.e("orientation",""+orientation); Matrix m=new Matrix(); if((orientation==3)){ m.postRotate(180); m.postScale((float)bm.getWidth(), (float)bm.getHeight()); // if(m.preRotate(90)){ Log.e("in orientation",""+orientation); bitmap = Bitmap.createBitmap(bm, 0, 0,bm.getWidth(),bm.getHeight(), m, true); return bitmap; } else if(orientation==6){ m.postRotate(90); Log.e("in orientation",""+orientation); bitmap = Bitmap.createBitmap(bm, 0, 0,bm.getWidth(),bm.getHeight(), m, true); return bitmap; } else if(orientation==8){ m.postRotate(270); Log.e("in orientation",""+orientation); bitmap = Bitmap.createBitmap(bm, 0, 0,bm.getWidth(),bm.getHeight(), m, true); return bitmap; } return bitmap; } catch (Exception e) { } return null; } 

Проблема в том, что вы должны поместить информацию exif вручную в свою функцию onPictureTaken .

После сохранения изображения (jpg) вы должны создать интерфейс Exif и сами поставить параметры:

 .... exif = new ExifInterface(file.getAbsolutePath()); exif.setAttribute(ExifInterface.TAG_ORIENTATION, orientation_detected_by_you_application); exif.saveAttributes(); 

Другие фотографии, которые у вас есть на телефоне, сделаны с помощью приложения, которое помещает информацию exif в изображения, которые она принимает.

Чтобы определить ориентацию:

 public void enableOrientationListener(){ if (mOrientationEventListener == null) { mOrientationEventListener = new OrientationEventListener(getContext(), SensorManager.SENSOR_DELAY_NORMAL) { @Override public void onOrientationChanged(int orientation) { // determine our orientation based on sensor response int lastOrientation = mOrientation; Display display = null; if(parentActivity == null){ display = ((WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); }else{ display = parentActivity.getWindowManager().getDefaultDisplay(); } if (display.getOrientation() == Surface.ROTATION_0) { // landscape oriented devices if (orientation >= 315 || orientation < 45) { if (mOrientation != ORIENTATION_LANDSCAPE_NORMAL) { mOrientation = ORIENTATION_LANDSCAPE_NORMAL; } } else if (orientation < 315 && orientation >= 225) { if (mOrientation != ORIENTATION_PORTRAIT_INVERTED) { mOrientation = ORIENTATION_PORTRAIT_INVERTED; } } else if (orientation < 225 && orientation >= 135) { if (mOrientation != ORIENTATION_LANDSCAPE_INVERTED) { mOrientation = ORIENTATION_LANDSCAPE_INVERTED; } } else if (orientation <135 && orientation > 45) { if (mOrientation != ORIENTATION_PORTRAIT_NORMAL) { mOrientation = ORIENTATION_PORTRAIT_NORMAL; } } } else { // portrait oriented devices if (orientation >= 315 || orientation < 45) { if (mOrientation != ORIENTATION_PORTRAIT_NORMAL) { mOrientation = ORIENTATION_PORTRAIT_NORMAL; } } else if (orientation < 315 && orientation >= 225) { if (mOrientation != ORIENTATION_LANDSCAPE_NORMAL) { mOrientation = ORIENTATION_LANDSCAPE_NORMAL; } } else if (orientation < 225 && orientation >= 135) { if (mOrientation != ORIENTATION_PORTRAIT_INVERTED) { mOrientation = ORIENTATION_PORTRAIT_INVERTED; } } else if (orientation <135 && orientation > 45) { if (mOrientation != ORIENTATION_LANDSCAPE_INVERTED) { mOrientation = ORIENTATION_LANDSCAPE_INVERTED; } } } } }; } if (mOrientationEventListener.canDetectOrientation()) { mOrientationEventListener.enable(); } } private static final int ORIENTATION_PORTRAIT_NORMAL = 1; private static final int ORIENTATION_PORTRAIT_INVERTED = 2; private static final int ORIENTATION_LANDSCAPE_NORMAL = 3; private static final int ORIENTATION_LANDSCAPE_INVERTED = 4; public void disableOrientationListener(){ if(mOrientationEventListener != null){ mOrientationEventListener.disable(); } } 

И вы должны установить mOrientation как атрибут ориентации для изображения.

Эта проблема была решена давно, но я столкнулся с некоторыми трудностями, чтобы сделать работу камеры правильной, поэтому вот мое окончательное решение, без использования exif. Надеюсь, это поможет другим:

 public void startPreview() { try { Log.i(TAG, "starting preview: " + started); // .... Camera.CameraInfo camInfo = new Camera.CameraInfo(); Camera.getCameraInfo(cameraIndex, camInfo); int cameraRotationOffset = camInfo.orientation; // ... Camera.Parameters parameters = camera.getParameters(); List previewSizes = parameters.getSupportedPreviewSizes(); Camera.Size previewSize = null; float closestRatio = Float.MAX_VALUE; int targetPreviewWidth = isLandscape() ? getWidth() : getHeight(); int targetPreviewHeight = isLandscape() ? getHeight() : getWidth(); float targetRatio = targetPreviewWidth / (float) targetPreviewHeight; Log.v(TAG, "target size: " + targetPreviewWidth + " / " + targetPreviewHeight + " ratio:" + targetRatio); for (Camera.Size candidateSize : previewSizes) { float whRatio = candidateSize.width / (float) candidateSize.height; if (previewSize == null || Math.abs(targetRatio - whRatio) < Math.abs(targetRatio - closestRatio)) { closestRatio = whRatio; previewSize = candidateSize; } } int rotation = getWindowManager().getDefaultDisplay().getRotation(); int degrees = 0; switch (rotation) { case Surface.ROTATION_0: degrees = 0; break; // Natural orientation case Surface.ROTATION_90: degrees = 90; break; // Landscape left case Surface.ROTATION_180: degrees = 180; break;// Upside down case Surface.ROTATION_270: degrees = 270; break;// Landscape right } int displayRotation; if (isFrontFacingCam) { displayRotation = (cameraRotationOffset + degrees) % 360; displayRotation = (360 - displayRotation) % 360; // compensate // the // mirror } else { // back-facing displayRotation = (cameraRotationOffset - degrees + 360) % 360; } Log.v(TAG, "rotation cam / phone = displayRotation: " + cameraRotationOffset + " / " + degrees + " = " + displayRotation); this.camera.setDisplayOrientation(displayRotation); int rotate; if (isFrontFacingCam) { rotate = (360 + cameraRotationOffset + degrees) % 360; } else { rotate = (360 + cameraRotationOffset - degrees) % 360; } Log.v(TAG, "screenshot rotation: " + cameraRotationOffset + " / " + degrees + " = " + rotate); Log.v(TAG, "preview size: " + previewSize.width + " / " + previewSize.height); parameters.setPreviewSize(previewSize.width, previewSize.height); parameters.setRotation(rotate); camera.setParameters(parameters); camera.setPreviewDisplay(mHolder); camera.startPreview(); Log.d(TAG, "preview started"); started = true; } catch (IOException e) { Log.d(TAG, "Error setting camera preview: " + e.getMessage()); } } 

Вы игнорируете исключение:

  try { // Code int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); } catch (Exception e) { } 

Пытаться :

  try { // Code int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); } catch (Exception e) { e.printStackTrace(); } 

И сообщение logcat. Никогда не бывает разумным исключать исключения.

  • Предназначение камеры Android Сохранение ландшафта изображения при съемке
  • Заставить камеру всегда открывать в портретном режиме в android
  • Активность kill / onCreate вызвана после съемки с помощью намерения
  • Android MediaRecorder - «start failed: -19»
  • Android-камера android.hardware.Camera устарела
  • Давайте будем гением компьютера.