如何正确设置Android相机方向?
我想根据 Android 中的设备方向设置相机方向,但似乎没有任何效果。我尝试旋转 Surface 以及相机参数,但纵向模式下的相机预览总是上下颠倒。我需要将其顺时针旋转 90 度才能正确。这是我现在使用的代码,仅适用于横向模式。
SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
camera = null;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
initCamera();
}
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.2;
double targetRatio = (double) w / h;
if (sizes == null)
return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
// Try to find an size match aspect ratio and size
for (Size size : sizes) {
Log.d(TAG, "Checking size " + size.width + "w " + size.height
+ "h");
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);
}
}
// Cannot find the one match the aspect ratio, ignore the
// requirement
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;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Camera.Parameters parameters = camera.getParameters();
List<Size> sizes = parameters.getSupportedPreviewSizes();
Size optimalSize = getOptimalPreviewSize(sizes, width, height);
Log.d(TAG, "Surface size is " + width + "w " + height + "h");
Log.d(TAG, "Optimal size is " + optimalSize.width + "w " + optimalSize.height + "h");
parameters.setPreviewSize(optimalSize.width, optimalSize.height);
// parameters.setPreviewSize(width, height);
camera.setParameters(parameters);
camera.startPreview();
}
};
I want to set the camera orientation according to the device orientation in Android but nothing seems to be working. I tried to rotate the Surface as well as the camera parameters but the camera preview in portrait mode always comes upside down. I would need to rotate it by 90 degree clockwise for it to be correct. Here is the code I am using right now which works in landscape mode only.
SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
camera = null;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
initCamera();
}
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.2;
double targetRatio = (double) w / h;
if (sizes == null)
return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
// Try to find an size match aspect ratio and size
for (Size size : sizes) {
Log.d(TAG, "Checking size " + size.width + "w " + size.height
+ "h");
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);
}
}
// Cannot find the one match the aspect ratio, ignore the
// requirement
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;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Camera.Parameters parameters = camera.getParameters();
List<Size> sizes = parameters.getSupportedPreviewSizes();
Size optimalSize = getOptimalPreviewSize(sizes, width, height);
Log.d(TAG, "Surface size is " + width + "w " + height + "h");
Log.d(TAG, "Optimal size is " + optimalSize.width + "w " + optimalSize.height + "h");
parameters.setPreviewSize(optimalSize.width, optimalSize.height);
// parameters.setPreviewSize(width, height);
camera.setParameters(parameters);
camera.startPreview();
}
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
来自其他成员和我的问题:
相机旋转问题取决于不同的设备和特定版本。
版本 1.6:修复旋转问题,对大多数设备都有好处
版本 2.1:取决于设备类型,例如,无法修复 XPeria X10 的问题,但对 X8 有好处,迷你
版本 2.2:不行适用于所有设备
http://code.google.com/p/ android/issues/detail?id=1193#c42
From other member and my problem:
Camera Rotation issue depend on different Devices and certain Version.
Version 1.6: to fix the Rotation Issue, and it is good for most of devices
Version 2.1: depend on kind of devices, for example, Cannt fix the issue with XPeria X10, but it is good for X8, and Mini
Version 2.2: not for all devices
http://code.google.com/p/android/issues/detail?id=1193#c42
来自
setDisplayOrientation(int)
(需要 API 级别 9):From the Javadocs for
setDisplayOrientation(int)
(Requires API level 9):此解决方案适用于所有版本的 Android。您可以在 Java 中使用反射来使其适用于所有 Android 设备:
基本上您应该创建一个反射包装器来调用 Android 2.2 setDisplayOrientation,而不是调用特定的方法。
方法:
不要使用camera.setDisplayOrientation(x),而是使用setDisplayOrientation(camera, x):
This solution will work for all versions of Android. You can use reflection in Java to make it work for all Android devices:
Basically you should create a reflection wrapper to call the Android 2.2 setDisplayOrientation, instead of calling the specific method.
The method:
And instead of using camera.setDisplayOrientation(x) use setDisplayOrientation(camera, x) :
当我使用 ZBar 在选项卡中进行扫描时,我遇到了这个问题。
相机方向问题。使用下面的代码我能够解决问题。
这不是完整的代码片段,请仅从中获取帮助。
I faced the issue when i was using ZBar for scanning in tabs.
Camera orientation issue. Using below code i was able to resolve issue.
This is not the whole code snippet, Please take only help from this.
我终于使用谷歌的相机应用程序解决了这个问题。它通过使用传感器获取手机的方向,然后适当地设置 EXIF 标签。从相机出来的 JPEG 不会自动定向。
此外,相机预览仅在横向模式下才能正常工作。如果您需要将活动布局设置为纵向,则必须使用方向传感器的值手动执行此操作。
I finally fixed this using the Google's camera app. It gets the phone's orientation by using a sensor and then sets the EXIF tag appropriately. The JPEG which comes out of the camera is not oriented automatically.
Also, the camera preview works properly only in the landscape mode. If you need your activity layout to be oriented in portrait, you will have to do it manually using the value from the orientation sensor.
这个问题很久以前就已经解决了,但我在将所有部分组合在一起时遇到了一些困难,所以这是我的最终解决方案,我希望这对其他人有帮助:
This problem was solved a long time ago but I encountered some difficulties to put all pieces together so here is my final solution, I hope this will help others :
看看这个解决方案
check out this solution