自定义相机活动的 Android 图像方向问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11674816/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android image orientation issue with custom camera activity
提问by Bryan
I wrote a custom camera activity to handle some issues I've been having with certain android devices when calling intent image capture. The user is able to either select save image or just use the data returned back from the OnPictureTakenCallback
.
我编写了一个自定义相机活动来处理在调用意图图像捕获时我在某些 android 设备上遇到的一些问题。用户可以选择保存图像或仅使用从OnPictureTakenCallback
.
The problem I'm having is displaying the image correctly with respect to the orientation it was taken. I force the activity to be displayed in portrait by calling SetRequestedOrientation
.
我遇到的问题是根据拍摄的方向正确显示图像。我通过调用强制活动以纵向显示SetRequestedOrientation
。
How would I know the correct Orientation the camera was in when the user took the picture? i.e. The user could take the picture at a rotation of 90 (portrait).
我如何知道用户拍照时相机的正确方向?即用户可以旋转 90 度(纵向)拍照。
I've tried to get to use the getRotation()
on the window manager's default display, but with setting the requested orientation to portrait that only returns Surface.ROTATION_0
.
我试图getRotation()
在窗口管理器的默认显示上使用 ,但是将请求的方向设置为仅返回Surface.ROTATION_0
.
Update:
To clarify my other issue, how could I determine the orientation from just the byte[]
data in the picture callback if the user were to not save the image?
更新:为了澄清我的另一个问题,byte[]
如果用户不保存图像,我如何仅根据图片回调中的数据确定方向?
Update: After trying the answers below with this code all I'm getting is ExifInterface.ORIENTATION_NORMAL. I've also changed my code to just save the file returned from the camera as I'm not sure there is an easy way to determine the orientation with just having the byte[]
data.
更新:在使用此代码尝试下面的答案后,我得到的只是 ExifInterface.ORIENTATION_NORMAL。我还更改了我的代码以仅保存从相机返回的文件,因为我不确定是否有一种简单的方法可以仅通过byte[]
数据来确定方向。
private PictureCallback mPicture = new PictureCallback()
{
@Override
public void onPictureTaken(byte[] data, Camera camera)
{
File directory = new File(android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_PICTURES),
"MyApp");
if(!directory.exists())
{
if(!directory.mkdirs())
{
Log.d("CAMERA", "Unable to create directory to save photos.");
return;
}
}
File file = new File(directory.getPath() + file.separator + "IMG_" + SimpleDateFormat.getDateTimeInstance().toString() + ".jpg");
FileOutputStream fos = new FileOutputStream(file);
fos.write(data);
fos.close();
ExifInterface exif = new ExifInterface(file.getCanonicalPath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int rotate = 0;
switch (orientation)
{
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case default:
break;
}
}
};
回答by Android2390
SO you are facing some issue with the orientation of the camera.
所以你在相机的方向上遇到了一些问题。
This link shows an example app of a simple camera capture activity : http://labs.makemachine.net/2010/03/simple-android-photo-capture/
此链接显示了一个简单的相机捕获活动的示例应用程序:http: //labs.makemachine.net/2010/03/simple-android-photo-capture/
Maybe you should try fixing the orientation by doing something like this :
也许您应该尝试通过执行以下操作来修复方向:
ExifInterface exif = new ExifInterface(_path);
int exifOrientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
int rotate = 0;
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
}
if (rotate != 0) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
// Setting pre rotate
Matrix mtx = new Matrix();
mtx.preRotate(rotate);
// Rotating Bitmap & convert to ARGB_8888, required by tess
bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, false);
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
}
回答by bsempe
You will need to read the Metadata from the original JPEG to verify the orientation in which the picture was taken.
您需要从原始 JPEG 中读取元数据以验证拍摄照片的方向。
ExifInterface exif = new ExifInterface(SourceFileName);
String exifOrientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
Source: How to determine orientation of picture without ExifInterface?
来源:如何在没有 ExifInterface 的情况下确定图片的方向?
Edit: Answering your edit, have you tried using the getCameraInfo() method that is available with the Camera object passed in the callback? Does it have the info you require?
编辑:回答您的编辑,您是否尝试过使用回调中传递的 Camera 对象可用的 getCameraInfo() 方法?它有你需要的信息吗?
Source: http://developer.android.com/reference/android/hardware/Camera.html
来源:http: //developer.android.com/reference/android/hardware/Camera.html
回答by Nikola Sokolov
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(holder);
Camera.Parameters parameters = mCamera.getParameters();
if (this.getResources().getConfiguration().orientation !=
Configuration.ORIENTATION_LANDSCAPE)
{
parameters.set("orientation", "portrait"); <----THis gets the job done!!!
// For Android Version 2.2 and above
mCamera.setDisplayOrientation(90);
// For Android Version 2.0 and above
parameters.setRotation(90);
}
// End Effects for Android Version 2.0 and higher
mCamera.setParameters(parameters);
}
catch (IOException exception)
{
mCamera.release();
}
}
回答by Bryan
Removing the setRequestedOrientation()
allowed getWindowManager().getDefaultDisplay().getRotation()
to give the correct rotation. I guess setting the requested orientation prevents the activity from redrawing itself when the configuration changes thus the device doesn't know any kind of rotation changed. My only issue now is switching from landscape mode at 0 degrees orientation to landscape mode 180 degrees rotation does not fire this:
删除setRequestedOrientation()
允许getWindowManager().getDefaultDisplay().getRotation()
给出正确的旋转。我想设置请求的方向可以防止活动在配置更改时重新绘制自身,因此设备不知道任何类型的旋转更改。我现在唯一的问题是从 0 度方向的横向模式切换到 180 度旋转的横向模式不会触发:
@Override
public void onConfigurationChanged(Configuration newconfig)
{
super.onConfigurationChanged(newconfig);
}