如何实现 Android 相机以任何屏幕方向拍照?
Posted
技术标签:
【中文标题】如何实现 Android 相机以任何屏幕方向拍照?【英文标题】:How can I implement the Android camera to take photos in any screen orientation? 【发布时间】:2011-07-20 06:53:50 【问题描述】:我希望相机的方向在手机旋转时不会改变,从而允许相机在任何方向拍摄一张直立的照片。目前,除了一个方向,图片在所有方向上都旋转不正确。在运行 2.2 的 HTC Incredible 上测试:
纵向模式的图像旋转90度,旋转它应该是什么。 装置从肖像逆时针旋转,产生180度的图像。 从肖像顺时针旋转的装置产生具有正确方向的图像。这里是相机实现的相关代码:
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
// Set up camera's SurfaceView and SurfaceHolder
surfaceView = (SurfaceView) findViewById(R.id.camera_surface);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height)
Camera.Parameters p = camera.getParameters();
p.setPreviewSize(width,height);
public void surfaceCreated(SurfaceHolder holder)
camera = Camera.open();
try
camera.setPreviewDisplay(surfaceHolder);
catch (IOException e)
camera.release();
camera.startPreview();
由于我希望应用程序与任何等于或高于 4 的 API 级别兼容以最大化用户群,我希望答案不使用特定于更高 API 级别的任何内容。谢谢!
【问题讨论】:
【参考方案1】:如果您不希望预览也旋转,请在清单文件中将方向设置为横向或纵向模式。
要获得正确旋转的图像,您需要在相机参数上调用 setRotation()(API 级别 5),然后在调用 takePicture API 之前设置该参数。您还需要使用orientationEventListener
示例代码here
【讨论】:
【参考方案2】:试试这个,但我认为这是错误。我也有这个问题,但在我的情况下,我找不到任何东西。
此代码可能是正确的,并且在您使用相机预览时可能对您有所帮助。
如果没有 - 此代码对您没有帮助。我在没有相机的情况下使用,所以它对我没有帮助。
public void surfaceCreated(SurfaceHolder holder)
try
camera.setPreviewDisplay(holder);
camera.setPreviewCallback(this);
catch (IOException e)
e.printStackTrace();
Size previewSize = camera.getParameters().getPreviewSize();
float aspect = (float) previewSize.width / previewSize.height;
int previewSurfaceWidth = preview.getWidth();
int previewSurfaceHeight = preview.getHeight();
LayoutParams lp = preview.getLayoutParams();
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE)
// ïîðòðåòíûé âèä
camera.setDisplayOrientation(90);
lp.height = previewSurfaceHeight;
lp.width = (int) (previewSurfaceHeight / aspect);
else
camera.setDisplayOrientation(0);
lp.width = previewSurfaceWidth;
lp.height = (int) (previewSurfaceWidth / aspect);
preview.setLayoutParams(lp);
camera.startPreview();
【讨论】:
很遗憾,setDisplayOrientation 仅适用于 API 级别 8 及以上:link 旧 API 版本的 setDisplayOrientation 的替代方法是 Camera.Parameters parameters = mCamera.getParameters(); parameters.set("旋转", 度数); mCamera.setParameters(参数);【参考方案3】:这应该考虑到任何屏幕方向,包括前后摄像头的不同处理:
// Set camera rotation (consider display orientation)
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
int displayOrientation = display.getRotation();
int rotation = cameraInfo.orientation;
if (Surface.ROTATION_0 != displayOrientation)
if (CameraInfo.CAMERA_FACING_BACK == cameraInfo.facing)
if (Surface.ROTATION_90 == displayOrientation)
rotation -= 90;
else if (Surface.ROTATION_180 == displayOrientation)
rotation -= 180;
if (Surface.ROTATION_270 == displayOrientation)
rotation -= 270;
if (rotation < 0)
rotation += 360;
else
if (Surface.ROTATION_90 == displayOrientation)
rotation += 90;
else if (Surface.ROTATION_180 == displayOrientation)
rotation += 180;
if (Surface.ROTATION_270 == displayOrientation)
rotation += 270;
rotation %= 360;
Log.d(TAG, "Camera orientation (" + cameraInfo.orientation + ", " + displayOrientation + ", " + rotation + ")");
cameraParams.setRotation(rotation);
【讨论】:
以上是关于如何实现 Android 相机以任何屏幕方向拍照?的主要内容,如果未能解决你的问题,请参考以下文章
即使 autoRotation 关闭,也能获取 android 设备方向