使用Camera API和预览SurfaceView
在设备处于人像状态下拍摄照片后,创建的图像将旋转90度。我知道这是一个影响某些 Android手机的问题,包括我正在开发的三星Galaxy S5 - 有几个堆栈溢出问题 - see here和here 。建议图像文件包含EXIF元数据,该元数据将说明旋转的方向,以便您可以使用它来旋转图像以获得正确的方向。我已经做到了这一点,但出于某种原因,ExifInterface.TAG_ORIENTATION
是1
- ORIENTATION_NORMAL
。因此,我无法确定需要旋转多少图像以确保它可以在所有设备上运行。即使该解决方案似乎对其他人有效。我做错了什么,或者这个问题怎么解决?
一些伪代码:
//in onCreate
camera = getCameraInstance();
setCameraDisplayOrientation(this, cameraID, camera);
//in OnClickListener
camera.takePicture(null, null, picCallback);
//callback:
onPictureTaken {
//create a File using getExternalStoragePublicDirectory(PICTURES) + "appname" - create directory if doesn't exist
//write file to disk via FileOutputStream
//attempt to correct the image orientation if needed
Bitmap correctBitmap = getCorrectOrientationBitmap(picFile.getAbsolutePath());
}
public Bitmap getCorrectOrientationBitmap(String photoFilePath) {
// Read EXIF Data
ExifInterface exif = null;
try {
exif = new ExifInterface(photoFilePath);
} catch (IOException e) {
e.printStackTrace();
return null;
}
String orientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
//problem: orientation is 1 - ORIENTATION_NORMAL despite the fact the image is rotated to the right 90 degrees
//rotate the image based on EXIF orientation
}
//later on
myImageView.setImageBitmap(correctBitmap);
//shows image rotated to the right because getCorrectOrientationBitmap didn't rotate it
答案 0 :(得分:0)
- EDIT-- 在我的代码中......
matrix.postRotate(旋转);
使用felix代码从光标返回的“rotation”值。
我认为你的照片有一个URI ....看看界面与使用类型的静态attr值....
public static int getOrientation(Context context, Uri photoUri) {
/* it's on the external media. */
Cursor cursor = context.getContentResolver().query(photoUri,
new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null);
if(null == cursor){
return -1;
}
if (cursor.getCount() != 1) {
return -1;
}
.....
if (getOrientation(mctx, mURI) != 0 && != -1) doRotate();
public doRotate(){
Bitmap lbit =
BitmapFactory.decodeStream( getContentResolver().openInputStream(_uri),null,options);
Log.i(TAG, "Rotating... " + rotation);
lbit = lbit.copy(Bitmap.Config.ARGB_8888, true);
Matrix matrix = new Matrix();
matrix.postRotate(rotation);
lbit = Bitmap.createBitmap(lbit, 0, 0, lbit.getWidth(),
lbit.getHeight(), matrix, true);
Picture.setBmp(lbit);
cursor.moveToFirst();
return cursor.getInt(0);
}
}
答案 1 :(得分:0)
前一段时间我正在玩这个问题,并在GitHub here上发布了一些相机代码。问题是你要处理3个不同的实体:
在上述示例中,我rotate the final的图片数量与我旋转preview at the beginning时的数量相同。我还没有在S5上测试过,所以如果你这样做,请告诉我它是否适用。
还有一件事,一些平板电脑也存在问题(see readme.md),其中一些平板电脑有'natural' orientation landscape (Nex7 1Gen),其他平板电脑(Nex7 2Gen)的画像与手机相同。
祝你好运
答案 2 :(得分:0)
使用图片回调而不是相机捕捉意图时,不会设置EXIF方向。但另一方面,当用户点击“捕获”按钮或其等效按钮时,您可以确切地知道设备方向。
如果您的活动被锁定在纵向方向,则变得更加容易 - 您可以无条件地将旋转旋转90°。
在内存和性能方面,位图旋转可能相当昂贵,因此如果通过设置正确的TAG_ORIENTATION
来满足您的用例,则只需将此更改应用于您保存的图像。请注意ExifInterface
适用于文件,而不是byte[]
,因此违反直觉,您应首先保存缓冲区,然后应用旋转,然后再次保存。
答案 3 :(得分:-1)
在拍照之前,根据当前的设备方向,需要setDisplayOrientation()。这不是自动完成的,默认情况下始终设置为0度,通常对应于横向。
这不是Galaxy s5问题