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

前端 未结 4 479
南方客
南方客 2020-11-27 16:24

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 val

相关标签:
4条回答
  • 2020-11-27 16:56

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

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

    0 讨论(0)
  • 2020-11-27 16:57

    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.

    0 讨论(0)
  • 2020-11-27 17:02

    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 < 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;
             }
    
    0 讨论(0)
  • 2020-11-27 17:13

    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<Camera.Size> 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());
            }
        }
    
    0 讨论(0)
提交回复
热议问题