EXIF orientation tag value always 0 for image taken with portrait camera app android

匿名 (未验证) 提交于 2019-12-03 02:23:02

问题:

I have a camera app in portrait mode which takes pictures from both front and back end cameras.I am saving the image in my sd card and try to find the corresponding exif value which gives 0 always.But i am getting the the expected exif orientation value for the other images stored in the device(like downloaded pictures).

How can i fix this ? Can anyone help me out ?

Here is the code used to save the picture and the find the orientation

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) {                  }        } }; 

Following is the code for surphace created and changed functions

@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) 

回答1:

I also faced same issue in Samsung devices, later I implemented ExifInterface and solved successfully.

In any mode images will be shot it will always store in portrait mode only, and while fetching too returning in portrait mode. below of code I used to achieve my goal, I implemented within back camera, not sure about from camera.

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 


回答2:

The problem is that you must put the exif information manually in your onPictureTaken function.

After you save the picture (jpg) you must create an Exif interface an put the parameters yourself:

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

The other pictures you have in your phone are made with the an application that puts the exif information in the pictures it takes.

To detect orientation:

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 = 225) {                         if (mOrientation != ORIENTATION_PORTRAIT_INVERTED) {                             mOrientation = ORIENTATION_PORTRAIT_INVERTED;                         }                                            } else if (orientation = 135) {                         if (mOrientation != ORIENTATION_LANDSCAPE_INVERTED) {                             mOrientation = ORIENTATION_LANDSCAPE_INVERTED;                         }                                            } else if (orientation  45) {                          if (mOrientation != ORIENTATION_PORTRAIT_NORMAL) {                             mOrientation = ORIENTATION_PORTRAIT_NORMAL;                         }                                            }                                        } else {  // portrait oriented devices                     if (orientation >= 315 || orientation = 225) {                         if (mOrientation != ORIENTATION_LANDSCAPE_NORMAL) {                             mOrientation = ORIENTATION_LANDSCAPE_NORMAL;                         }                                            } else if (orientation = 135) {                         if (mOrientation != ORIENTATION_PORTRAIT_INVERTED) {                             mOrientation = ORIENTATION_PORTRAIT_INVERTED;                         }                                            } else if (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();     } } 

And you should set mOrientation as orientation attribute for you image.



回答3:

This problem was solved a long time ago but I encountered some difficulties to make camera work correctly so here is my final solution, without using exif. I hope this will help others :

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) 


回答4:

You are ignoring an Exception at :

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

Try :

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

And post logcat. It is never wise to thow away exceptions.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!