EXIF方向标记值图像总是0采取肖像相机应用程式android(EXIF orientation t

2019-06-18 21:39发布

我在人像模式的相机应用程序,它需要来自前端和后端cameras.I图片我在我的SD卡保存图像,并设法找到相应的EXIF值给出0 always.But我收到预期的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) {

                }



    }
};

以下是surphace创建和更改的功能代码

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
List<Size> 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 < Camera.getNumberOfCameras(); i++) {
            Camera.getCameraInfo(i, info);

            if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
              camera=Camera.open(i);
              defaultCameraId = i;
            }
          }
        }

        if (camera == null) {
          camera=Camera.open();
        }




        try {
            camera.setPreviewDisplay(surfaceHolder);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        Camera.Parameters parameters = camera.getParameters();
        android.hardware.Camera.CameraInfo info =
                new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(defaultCameraId, info);
        int rotation = this.getWindowManager().getDefaultDisplay()
                .getRotation();
        if (Integer.parseInt(Build.VERSION.SDK) >= 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<Size> 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;
        }

Answer 1:

我也面临同样的问题,在三星设备,后来我实现ExifInterface和成功地解决了。

在任何模式下图像将被拍摄的,它会永远在纵向模式下保存,并同时获取在纵向模式下也返回。 下面我用来实现我的目标代码,我背部摄像头内实现,不知道从相机。

相机意图@

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


Answer 2:

问题是,你必须手动将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为你形象定位属性。



Answer 3:

这个问题已经解决很久以前的事,但我遇到了一些困难,使相机能正常工作所以这里是我的最终解决方案,而无需使用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<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());
        }
    }


Answer 4:

您忽略在一个例外:

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

和POST logcat的。 这是从来没有明智的thow走例外。



文章来源: EXIF orientation tag value always 0 for image taken with portrait camera app android