Android中的相机方向问题

我正在构build一个使用相机拍照的应用程序。 这是我的源代码来做到这一点:

File file = new File(Environment.getExternalStorageDirectory(), imageFileName); imageFilePath = file.getPath(); Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); //Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); startActivityForResult(intent, ACTIVITY_NATIVE_CAMERA_AQUIRE); 

onActivityResult()方法上,我使用BitmapFactory.decodeStream()来拾取图像。

当我在Nexus上运行我的应用程序时,它运行良好。 但是当我在三星Galaxy S或HTC Inspire 4G上运行时,图像的方向是不正确的。

  • 用肖像模式拍摄,真实图像(保存在SD卡上)总是旋转90度。

镜头后的图像预览SD卡上的真实图像

拍摄后图像预览——— SD卡上的真实图像

  • 捕捉景观模式,一切都很好。

拍摄后的图像预览SD卡上的真实图像

拍摄后图像预览——— SD卡上的真实图像

这里有相当多的话题和问题。 既然你不写自己的相机,我认为这归结为:

有些设备会在保存图像之前旋转图像,而其他设备只需在照片的exif数据中添加方向标签。

我build议检查照片的exif数据,并特别寻找

 ExifInterface exif = new ExifInterface(SourceFileName); //Since API Level 5 String exifOrientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION); 

由于照片在您的应用程序中正确显示,我不知道问题出在哪里,但是这应该确保您在正确的道路上!

我刚刚遇到同样的问题,并用它来纠正方向:

 public void fixOrientation() { if (mBitmap.getWidth() > mBitmap.getHeight()) { Matrix matrix = new Matrix(); matrix.postRotate(90); mBitmap = Bitmap.createBitmap(mBitmap , 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, true); } } 

如果位图的宽度大于高度,则返回的图像处于横向,所以我将它旋转90度。

希望它能帮助其他任何人解决这个问题。

有两件事情需要:

  1. 相机预览需要与您的旋转相同。 通过camera.setDisplayOrientation(result);

  2. 保存拍摄的照片作为相机预览。 通过Camera.Parameters做到这Camera.Parameters

     int mRotation = getCameraDisplayOrientation(); Camera.Parameters parameters = camera.getParameters(); parameters.setRotation(mRotation); //set rotation to save the picture camera.setDisplayOrientation(result); //set the rotation for preview camera camera.setParameters(parameters); 

希望有所帮助。

  int rotate = 0; try { File imageFile = new File(sourcepath); ExifInterface exif = new ExifInterface( imageFile.getAbsolutePath()); int orientation = exif.getAttributeInt( ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_270: rotate = 270; break; case ExifInterface.ORIENTATION_ROTATE_180: rotate = 180; break; case ExifInterface.ORIENTATION_ROTATE_90: rotate = 90; break; } } catch (Exception e) { e.printStackTrace(); } Matrix matrix = new Matrix(); matrix.postRotate(rotate); bitmap = Bitmap.createBitmap(bitmap , 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); 

另一个select是在结果屏幕上旋转位图,如下所示:

 ImageView img=(ImageView)findViewById(R.id.ImageView01); Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.refresh); // Getting width & height of the given image. int w = bmp.getWidth(); int h = bmp.getHeight(); // Setting post rotate to 90 Matrix mtx = new Matrix(); mtx.postRotate(90); // Rotating Bitmap Bitmap rotatedBMP = Bitmap.createBitmap(bmp, 0, 0, w, h, mtx, true); BitmapDrawable bmd = new BitmapDrawable(rotatedBMP); img.setImageDrawable(bmd); 

对于某些设备,我也有这种types的问题:

 private void rotateImage(final String path) { Bitmap scaledBitmap = Bitmap.createScaledBitmap(Conasants.bm1, 1000, 700, true); Bitmap rotatedBitmap = null; try { ExifInterface ei = new ExifInterface(path); int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); Matrix matrix = new Matrix(); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: matrix.postRotate(90); rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true); break; case ExifInterface.ORIENTATION_ROTATE_180: matrix.postRotate(180); rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true); break; case ExifInterface.ORIENTATION_ROTATE_270: matrix.postRotate(270); rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true); break; default: rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true); break; } } catch (Throwable e) { e.printStackTrace(); } cropImage.setImageBitmap(rotatedBitmap); rotatedBitmap = null; Conasants.bm1 = null; } 

不再检查照片的exif数据。 Glide轻松下去。

Google向我们介绍了一款名为Glide的由bumptech开发的Android图像加载器库,该库由Google推荐。 迄今为止,它已被用于许多Google开源项目,包括Google I / O 2014官方应用程序。

例如:Glide.with(context).load(uri).into(imageview);

更多: https : //github.com/bumptech/glide

试试这个方法:static Uri image_uri; 静态位图taken_image = null;

  image_uri=fileUri; // file where image has been saved taken_image=BitmapFactory.decodeFile(image_uri.getPath()); try { ExifInterface exif = new ExifInterface(image_uri.getPath()); int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch(orientation) { case ExifInterface.ORIENTATION_ROTATE_90: taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200); RotateBitmap(taken_image, 90); break; case ExifInterface.ORIENTATION_ROTATE_180: taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200); RotateBitmap(taken_image, 180); break; case ExifInterface.ORIENTATION_ROTATE_270: taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200); RotateBitmap(taken_image, 270); break; case ExifInterface.ORIENTATION_NORMAL: taken_image=decodeScaledBitmapFromSdCard(image_uri.getPath(), 200, 200); RotateBitmap(taken_image, 0); break; } } catch (OutOfMemoryError e) { Toast.makeText(getActivity(),e+"\"memory exception occured\"",Toast.LENGTH_LONG).show(); } public Bitmap RotateBitmap(Bitmap source, float angle) { Matrix matrix = new Matrix(); matrix.postRotate(angle); round_Image = source; round_Image = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true); return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true); 

}

 public void setCameraPicOrientation(){ int rotate = 0; try { File imageFile = new File(mCurrentPhotoPath); ExifInterface exif = new ExifInterface( imageFile.getAbsolutePath()); int orientation = exif.getAttributeInt( ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_270: rotate = 270; break; case ExifInterface.ORIENTATION_ROTATE_180: rotate = 180; break; case ExifInterface.ORIENTATION_ROTATE_90: rotate = 90; break; } } catch (Exception e) { e.printStackTrace(); } Matrix matrix = new Matrix(); matrix.postRotate(rotate); int targetW = 640; int targetH = 640; /* Get the size of the image */ BitmapFactory.Options bmOptions = new BitmapFactory.Options(); bmOptions.inJustDecodeBounds = true; BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions); int photoW = bmOptions.outWidth; int photoH = bmOptions.outHeight; /* Figure out which way needs to be reduced less */ int scaleFactor = 1; if ((targetW > 0) || (targetH > 0)) { scaleFactor = Math.min(photoW/targetW, photoH/targetH); } /* Set bitmap options to scale the image decode target */ bmOptions.inJustDecodeBounds = false; bmOptions.inSampleSize = scaleFactor; bmOptions.inPurgeable = true; /* Decode the JPEG file into a Bitmap */ Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions); bitmap= Bitmap.createBitmap(bitmap , 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); /* Associate the Bitmap to the ImageView */ imageView.setImageBitmap(bitmap); } 

希望这会有所帮助! 谢谢

  public static int mOrientation = 1; OrientationEventListener myOrientationEventListener; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.takephoto); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); myOrientationEventListener = new OrientationEventListener(getApplicationContext()) { @Override public void onOrientationChanged(int o) { // TODO Auto-generated method stub if(!isTablet(getApplicationContext())) { if(o<=285 && o>=80) mOrientation = 2; else mOrientation = 1; } else { if(o<=285 && o>=80) mOrientation = 1; else mOrientation = 2; } } }; myOrientationEventListener.enable(); } public static boolean isTablet(Context context) { return (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE; } } 

我希望这会有帮助。谢谢!

只是在这里遇到同样的问题,下面的代码片段适用于我:

 private static final String[] CONTENT_ORIENTATION = new String[] { MediaStore.Images.ImageColumns.ORIENTATION }; static int getExifOrientation(ContentResolver contentResolver, Uri uri) { Cursor cursor = null; try { cursor = contentResolver.query(uri, CONTENT_ORIENTATION, null, null, null); if (cursor == null || !cursor.moveToFirst()) { return 0; } return cursor.getInt(0); } catch (RuntimeException ignored) { // If the orientation column doesn't exist, assume no rotation. return 0; } finally { if (cursor != null) { cursor.close(); } } } 

希望这有助于:)

在surfaceChangedcallback中试试这个:

 Camera.Parameters parameters=mCamera.getParameters(); if(this.getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT){ parameters.setRotation(90); }else{ parameters.setRotation(0); } mCamera.setParameters(parameters); 

该代码是function的风景和肖像@frontCameraID =variables得到它的方法经典的显示相机想要的

 @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { if(holder.getSurface() == null) { return; } try{ camera.stopPreview(); } catch (Exception e){ } try{ int orientation = getDisplayOrientation(frontCameraID); Camera.Parameters parameters = camera.getParameters(); parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height); if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) { parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); } parameters.setRotation(rotationPicture); camera.setParameters(parameters); camera.setDisplayOrientation(orientation); camera.startPreview(); } catch (Exception e) { Log.i("ERROR", "Camera error changed: " + e.getMessage()); } } 

获取方向和旋转的方法来保存图片和显示方向@result =方向在相机的预览视图@ rotationPicture =正确地保存图片的旋转

 private int getDisplayOrientation(int cameraId) { android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); android.hardware.Camera.getCameraInfo(cameraId, info); int rotation = ((Activity) context).getWindowManager().getDefaultDisplay().getRotation(); 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; rotationPicture = (360 - result) % 360; } else { result = (info.orientation - degrees + 360) % 360; rotationPicture = result; } return result; } 

有人问关于代码,请告诉我。