2010-10-01 34 views
114

Tôi đang sử dụng Xem trước để hiển thị những gì máy ảnh nhìn thấy trên màn hình.Android - Xem trước máy ảnh nằm ngang

Tôi có thể làm mọi thứ hoạt động tốt, bề mặt được tạo, bộ bề mặt và bề mặt được hiển thị.

Tuy nhiên, nó luôn hiển thị hình ảnh ở góc 90 độ không chính xác ở chế độ dọc.

Chẳng hạn như trong hình:

alt text

Tôi biết rằng việc sử dụng đoạn mã sau sẽ thiết lập các hình ảnh thẳng:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 

Tuy nhiên tôi có xem trước trong một Hoạt động có các yếu tố khác trong nó và nó không có ý nghĩa cho hoạt động của tôi sẽ được hiển thị trong chế độ phong cảnh. (Tắt theo mặc định)

Vì vậy, tôi đã tự hỏi là có anyway để chỉ thay đổi định hướng của Xem trước? Và để phần còn lại của Hoạt động của tôi hiển thị chính xác ở chế độ Chân dung?

Hoặc dù sao để xoay bản xem trước sao cho nó được hiển thị chính xác?

+0

Có một cái nhìn - http://stackoverflow.com/questions/10259299/force-a-camera -to-always-open-in-portrait-mode-in-android/10259572 # 10259572 –

Trả lời

139

Vấn đề này xuất hiện để bắt đầu ra như là một lỗi phần cứng nhất định see here nhưng có thể được khắc phục bằng cách sử dụng các cuộc gọi đến mCamera.setDisplayOrientation (độ) có sẵn trong API 8. Vì vậy, đây là cách tôi thực hiện nó:

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);  
    } 
} 

Đây là trên HTC Desire và ban đầu tôi đã đưa vào các câu lệnh ghi nhật ký trong mỗi lần kiểm tra xoay để nói xoay vòng là gì và sau đó gỡ lỗi trên thiết bị và xem đầu ra logCat trong khi tôi xoay thiết bị. Đối với HTC Desire, 0 là điện thoại như bạn mong đợi (ảnh chân dung), 90 độ đã biến điện thoại 90 độ COUNTER-CLOCKWISE (tôi đã giả định nó sẽ có chiều kim đồng hồ). Trong mã bạn sẽ thấy tôi không cần phải quay bất kỳ màn hình nào khi điện thoại ở 90 hoặc 180 độ - thiết bị dường như tự xử lý nó. Chỉ có một điểm không hoạt động chính xác: Xoay 270 độ là khi bạn xoay thiết bị 90 độ theo chiều kim đồng hồ và màn hình xoay màn hình ok nhưng nếu bạn xoay thiết bị 270 độ ngược chiều kim đồng hồ, nó có vẻ không bù lại đúng.

P.S. Lưu ý việc hoán đổi chiều rộng và chiều cao trong các phép quay thích hợp.

+7

nhưng setDisplayOrientation (độ); phương pháp hỗ trợ hình thức 2.2, những gì về phiên bản thấp hơn ?? parameters.setRotation (90); \t \t \t parameters.set ("orientation", "portrait"); không hoạt động. Nếu bạn có bất kỳ giải pháp cho các phiên bản thấp hơn xin vui lòng giúp tôi. – Vikram

+1

Tôi đã triển khai bản xem trước trên ứng dụng sẽ luôn hiển thị ở chế độ dọc. Tôi luôn xoay màn hình 90 độ và điều này dường như hoạt động trên mọi thiết bị cho đến khi chúng tôi thử nghiệm trên HTC Desire C. Vì tôi không đếm trên thiết bị ngay bây giờ để kiểm tra điều này, tôi muốn bạn làm rõ đề nghị cuối cùng đã làm việc tốt trên mong muốn HTC. Cảm ơn! – Soflete

+0

Có, điều này đã làm việc tốt trên HTC Desire, trong trường hợp của tôi. –

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(); 
    } 
} 

thử mã này

+0

Cảm ơn bạn tốt đẹp dude –

+3

tại thời điểm lưu nó lưu hình ảnh chân dung trong landscape.Any giải pháp? –

+0

@Akanksha có thể liên quan đến các thông số EXIF. – EpicPandaForce

2

tôi nó lấy lời khuyên của mCamera.setDisplayOrientation (90); nhưng cũng xoay bitmap vì một số lý do mà các phương pháp khác không làm việc với tôi trong phiên bản 2.3.3.

Đối xoay bitmap tôi đã làm điều này:

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

cố gắng để thiết lập các định hướng hiển thị. Nó giải quyết vấn đề của tôi.

mCamera.setDisplayOrientation(90); 
+5

tại thời điểm lưu nó lưu hình ảnh chân dung trong phong cảnh. Bất kỳ giải pháp? –

+0

@Akanksha: cờ này chỉ áp dụng cho hiển thị xem trước. Nó không thay đổi hướng của bộ đệm được trả về trong 'onPreviewFrame()' hoặc 'onPictureTaken()' –

1

Tôi đã so sánh mã của mình với mã hướng dẫn và điều cuối cùng đã khắc phục là đặt mã sau vào AndroidManifext của tôi.xml: Trong thẻ <activity>:

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

Tôi gặp vấn đề với máy ảnh phía trước (vấn đề xuống Upside). Sau đó, tôi sử dụng phương pháp này

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

Phương thức này đến từ tài liệu hướng dẫn của máy ảnh: http://developer.android.com/reference/android/hardware/Camera.html #setDisplayOrientation (int) – VinceFior

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

Đoạn đường làm việc cho tôi một cách hoàn hảo

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

Điều này làm gì và cách khắc phục sự cố? –

Các vấn đề liên quan