我在onPictureTaken
中发现,保存的位图围绕y轴镜像,并顺时针旋转90度,即使相机预览没有。在我的Nexus S上运行2.3.6。在我的nexus 4和4.2上运行的同一个程序将生成的位图镜像到y轴上,并顺时针旋转180度。
这是我运行的代码:
@Override
public void onPictureTaken(final byte[] data, Camera camera) {
Bitmap picture = BitmapFactory.decodeByteArray(data, 0, data.length);
String path = MediaStore.Images.Media.insertImage(getContentResolver(), picture, "name" , "description");
Log.e("tag", "path: " + path); // prints something like "path: content://media/external/images/media/819"
try {
ExifInterface exif = new ExifInterface(path); // prints this error: "04-25 21:28:21.063: E/JHEAD(12201): can't open 'content://media/external/images/media/819'"
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
Log.e("tag", "exif orientation: " + orientation); // this is outputting orientation unknown
} catch (IOException e) {
e.printStackTrace();
}
}
有谁能告诉我,如果我从不同的设备得到不同的结果,我该如何纠正这个问题?如何检测结果位图的方向,以便知道将其逆时针旋转90度或180度?
[编辑]
我用我读过的现有接口添加了更多的信息,但这些信息似乎没有成功…
最佳答案
我为此做了很多工作,我想,我会分享我的解决方案。
它在摩托罗拉DEVY、三星XCOver1和三星XCOver2上进行了测试。
当我使用自定义相机预览时,解决方案基本上有两个
部分。
1。注意相机预览并根据
装置旋转。
2。一旦拍照,即调用“onPictureTaken”回调
以正确的角度旋转图片,使其显示预览
显示。
一
private void initPreview(int width, int height) {
if (camera != null && holder.getSurface() != null) {
try {
camera.setPreviewDisplay(holder);
} catch (Throwable t) {
Log.e("PreviewDemo-surfaceCallback",
"Exception in setPreviewDisplay()", t);
Toast.makeText(getContext(), t.getMessage(),
Toast.LENGTH_LONG).show();
}
try {
Camera.Parameters parameters=camera.getParameters();
Camera.Size size=getBestPreviewSize(width, height, parameters);
Camera.Size pictureSize=getSmallestPictureSize(parameters);
Display display = windowManager.getDefaultDisplay();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) { // for 2.1 and before
if (isPortrait(display)) {
parameters.set(CAMERA_PARAM_ORIENTATION, CAMERA_PARAM_PORTRAIT);
} else {
parameters.set(CAMERA_PARAM_ORIENTATION, CAMERA_PARAM_LANDSCAPE);
}
} else { // for 2.2 and later
switch (display.getRotation()) {
case Surface.ROTATION_0: // This is display orientation
if (size.height > size.width) parameters.setPreviewSize(size.height, size.width);
else parameters.setPreviewSize(size.width, size.height);
camera.setDisplayOrientation(90);
break;
case Surface.ROTATION_90:
if (size.height > size.width) parameters.setPreviewSize(size.height, size.width);
else parameters.setPreviewSize(size.width, size.height);
camera.setDisplayOrientation(0);
break;
case Surface.ROTATION_180:
if (size.height > size.width) parameters.setPreviewSize(size.height, size.width);
else parameters.setPreviewSize(size.width, size.height);
camera.setDisplayOrientation(270);
break;
case Surface.ROTATION_270:
if (size.height > size.width) parameters.setPreviewSize(size.height, size.width);
else parameters.setPreviewSize(size.width, size.height);
camera.setDisplayOrientation(180);
break;
}
}
parameters.setPictureSize(pictureSize.width, pictureSize.height);
//parameters.setPictureFormat(ImageFormat.JPEG);
camera.setParameters(parameters);
} catch (Exception e) {
e.printStackTrace();
}
}
}
“SurfaceChanged”方法,在相机预览(SurfaceView)中,
你应该像这样:
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
stopPreview();
initPreview(w, h);
startPreview();
}
在哪里?
停止预览:
private void stopPreview() {
if (camera != null) {
camera.stopPreview();
}
}
开始预览:
private void startPreview() {
if (camera != null) {
camera.startPreview();
}
}
二
在“onPictureTaken”回调中,使用以下代码旋转图片:
Display display = getWindowManager().getDefaultDisplay();
int rotation = 0;
switch (display.getRotation()) {
case Surface.ROTATION_0: // This is display orientation
rotation = 90;
break;
case Surface.ROTATION_90:
rotation = 0;
break;
case Surface.ROTATION_180:
rotation = 270;
break;
case Surface.ROTATION_270:
rotation = 180;
break;
}
Bitmap bitmap = BitmapTools.toBitmap(data);
bitmap = BitmapTools.rotate(bitmap, rotation);
位图工具.java
public class BitmapTools {
public static Bitmap toBitmap(byte[] data) {
return BitmapFactory.decodeByteArray(data , 0, data.length);
}
public static Bitmap rotate(Bitmap in, int angle) {
Matrix mat = new Matrix();
mat.postRotate(angle);
return Bitmap.createBitmap(in, 0, 0, in.getWidth(), in.getHeight(), mat, true);
}
}