2010-10-01 138 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