如何实现 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 相机以任何屏幕方向拍照?的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式在 Android 上使用相机拍照

即使 autoRotation 关闭,也能获取 android 设备方向

有没有办法打开相机并在屏幕上查看它并使其无法拍照或录制视频。

Android相机以人像模式保存图片

Android 相机预览在预览中拉伸,而不是在拍照后

android方向 - 意图问题(相机)