2010-10-01 139 views
114

我正在使用预览来显示相机在屏幕上显示的内容。Android - 相机预览横向

我可以使一切工作正常,表面创建,表面设置和表面显示。

但是,它总是在纵向模式下以不正确的90度角度显示图片。

如在图片:

alt text

据我所知,使用下面的代码将直接设置图片:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 

不过,我有一个活动中有预览其他元素,并且我的活动在横向模式下显示没有意义。 (它默认禁用)

所以我想知道是否有改变预览的方向?在肖像模式下正确显示我的活动的其余部分?

或者无论如何旋转预览,使其正确显示?

+0

看一看 - http://stackoverflow.com/questions/10259299/force-a-camera - 永远打开肖像模式在Android/10259572#10259572 – 2012-04-22 06:31:17

回答

139

这个问题似乎开始了与某些硬件see here一个错误,但可以通过使用(度)的API 8.可调用mCamera.setDisplayOrientation克服所以我这是怎么实现它:

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {    
    if (isPreviewRunning) { 
     mCamera.stopPreview(); 
    } 

    Parameters parameters = mCamera.getParameters(); 
    Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay(); 

    if(display.getRotation() == Surface.ROTATION_0) { 
     parameters.setPreviewSize(height, width);       
     mCamera.setDisplayOrientation(90); 
    } 

    if(display.getRotation() == Surface.ROTATION_90) { 
     parameters.setPreviewSize(width, height);       
    } 

    if(display.getRotation() == Surface.ROTATION_180) { 
     parameters.setPreviewSize(height, width);    
    } 

    if(display.getRotation() == Surface.ROTATION_270) { 
     parameters.setPreviewSize(width, height); 
     mCamera.setDisplayOrientation(180); 
    } 

    mCamera.setParameters(parameters); 
    previewCamera();      
} 

And the previewCamera method : 

public void previewCamera() {   
    try {   
     mCamera.setPreviewDisplay(mSurfaceHolder);   
     mCamera.startPreview(); 
     isPreviewRunning = true; 
    } catch(Exception e) { 
     Log.d(APP_CLASS, "Cannot start preview", e);  
    } 
} 

这是在HTC Desire上,我最初必须在每个旋转检查中放入日志语句,以说明旋转是什么,然后在设备上调试并在旋转设备时观看logCat输出。对于HTC Desire来说,0是你所期望的(肖像)手机,90度是把手机转向90度逆时针(我假设它会是顺时针方向)。在代码中,你会发现当手机处于90度或180度时,我不需要做任何显示旋转 - 该设备似乎自己处理这个问题。只有一个点不能正常工作:270度旋转是当您顺时针旋转设备90度并且显示器旋转计数器正常时,但是如果您将设备逆时针旋转270度,它似乎无法正确补偿。

P.S.请注意在适当的旋转中宽度和高度的交换。

+7

但setDisplayOrientation(度);方法支持表格2.2,低版本怎么样? parameters.setRotation(90); \t \t \t parameters.set(“orientation”,“portrait”);没有工作。如果你有更低版本的解决方案,请帮助我。 – Vikram 2011-11-01 15:11:12

+1

我在我的应用程序上实现了一个预览,它将始终以纵向模式显示。我一直在旋转90度的屏幕,这似乎在每台设备上都能正常工作,直到我们在HTC Desire C上进行测试。由于我现在不指望设备进行测试,我希望您澄清一下,建议最终在HTC的愿望上效果不错。谢谢! – Soflete 2012-12-19 14:10:35

+0

是的,这在HTC Desire上运行良好,就我而言。 – 2012-12-19 15:08:48

13
public void surfaceCreated(SurfaceHolder holder) { 
    mCamera = Camera.open(); 
    mCamera.setDisplayOrientation(90); 
    try { 
     mCamera.setPreviewDisplay(holder); 
     mCamera.setPreviewCallback(new PreviewCallback() { 

      @Override 
      public void onPreviewFrame(byte[] data, Camera camera) { 
      } 
     }); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

试试这个代码

+0

好心的感谢伙计 – 2013-06-21 10:01:52

+3

在保存的时候将纵向图像保存在landscape.Any解决方案? – 2013-12-30 11:55:01

+0

@Akanksha可能与EXIF参数有关。 – EpicPandaForce 2016-02-09 13:25:47

2

我这样做是考虑mCamera.setDisplayOrientation的意见(90);但也旋转位图,因为由于某种原因,其他方法在2.3.3版本中不适用于我。

对于旋转位图我这样做:

Matrix matrix = new Matrix(); 
matrix.postRotate(90); 
imageView1 = new ImageView(this); 
Bitmap bitmap = BitmapFactory.decodeFile(files[i].getAbsolutePath()); 
Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap , 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); 
Bitmap scaledBitmap = Bitmap.createScaledBitmap(rotatedBitmap, 80, 80, true); 
imageView1.setImageBitmap(scaledBitmap); 
15

尝试设置显示方向。它解决了我的问题。

mCamera.setDisplayOrientation(90); 
+5

保存时将纵向图像保存在横向。任何解决方案? – 2013-12-30 11:55:26

+0

@Akanksha:此标志仅适用于预览显示。它不会改变'onPreviewFrame()'或'onPictureTaken()'返回的缓冲区的方向。 – 2015-10-17 17:55:57

1

我将我的代码与教程1进行了比较,最终确定它将以下代码放入我的AndroidManifext中。XML: 在<activity>标签:

android:screenOrientation="landscape" 
android:configChanges="keyboardHidden|orientation"> 
1

我有前置摄像头(倒挂问题)问题。然后,我用这个方法

public void setCameraDisplayOrientation(Activity activity , int icameraId , Camera camera1s) 
    { 
     CameraInfo cameraInfo = new CameraInfo(); 

     Camera.getCameraInfo(icameraId, cameraInfo); 

     int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); 

     int degrees = 0; // k 

     switch (rotation) 
     { 
     case Surface.ROTATION_0: 
      degrees = 0; 
      break; 
     case Surface.ROTATION_90: 
      degrees = 90; 
      break; 
     case Surface.ROTATION_180: 
      degrees = 180; 
      break; 
     case Surface.ROTATION_270: 
      degrees = 270; 
      break; 

     } 

     int result; 

     if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) 
     { 
      // cameraType=CAMERATYPE.FRONT; 

      result = (cameraInfo.orientation + degrees) % 360; 
      result = (360 - result) % 360; // compensate the mirror 

     } 
     else 
     { // back-facing 

      result = (cameraInfo.orientation - degrees + 360) % 360; 

     } 
     // displayRotate=result; 
     camera.setDisplayOrientation(result); 


    } 
+1

这个方法来自相机文档:http://developer.android.com/reference/android/hardware/Camera.html #setDisplayOrientation(int) – VinceFior 2016-03-19 04:15:19

0
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
    // If your preview can change or rotate, take care of those events here. 
    // Make sure to stop the preview before resizing or reformatting it. 

    if (mHolder.getSurface() == null) { 
     // preview surface does not exist 
     return; 
    } 

    try { 
     mCamera.stopPreview(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    Camera.Parameters parameters = mCamera.getParameters(); 
    Display display = ((WindowManager) getContext().getSystemService(WINDOW_SERVICE)).getDefaultDisplay(); 

    if (display.getRotation() == Surface.ROTATION_0) { 
     parameters.setPreviewSize(h, w); 
     mCamera.setDisplayOrientation(90); 
    } 

    if (display.getRotation() == Surface.ROTATION_90) { 
     parameters.setPreviewSize(w, h); 
     mCamera.setDisplayOrientation(0); 
    } 

    if (display.getRotation() == Surface.ROTATION_180) { 
     parameters.setPreviewSize(h, w); 
     mCamera.setDisplayOrientation(270); 
    } 

    if (display.getRotation() == Surface.ROTATION_270) { 
     parameters.setPreviewSize(w, h); 
     mCamera.setDisplayOrientation(180); 
    } 

    previewCamera(); 
} 

public void previewCamera() { 
    try { 
     mCamera.setPreviewDisplay(mHolder); 
     mCamera.startPreview(); 
    } catch (Exception e) { 
     //Log.d(APP_CLASS, "Cannot start preview", e); 
     e.printStackTrace(); 
    } 
} 
-2

这片线完全为我工作

static { 
    ORIENTATIONS.append(Surface.ROTATION_0, 90); 
    ORIENTATIONS.append(Surface.ROTATION_90, 180); 
    ORIENTATIONS.append(Surface.ROTATION_180, 270); 
    ORIENTATIONS.append(Surface.ROTATION_270, 360); 
} 
+0

这是做什么以及它如何解决这个问题? – 2017-03-04 14:08:18