对于用肖像照相机app android拍摄的图像,EXIF方向标签值始终为0

我有一个肖像模式的相机应用程序,从前端和后端摄像头拍照。我将图像保存在我的SD卡上,并试图find相应的exif值,总是给出0。但是我得到了预期的exif方向存储在设备中的其他图像的值(如下载的图片)。

我该如何解决这个问题? 谁能帮我吗 ?

这里是用来保存图片和find方向的代码

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创build和更改函数的代码

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

我也在三星设备面临同样的问题,后来我实现了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; } 

问题是,您必须手动将exif信息放在onPictureTaken函数中。

保存图片(jpg)后,您必须创build一个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作为方向属性。

这个问题很久以前就解决了,但是我遇到了一些困难,使得相机能正常工作,所以这里是我的最终解决scheme,不用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()); } } 

您正在忽略例外:

  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。 除去exception是不明智的。