2012-07-04 34 views
23

Tôi có một ứng dụng Android cần toàn màn hình xem trước máy ảnh bất kể kích thước xem trước được đưa ra bởi getSupportedPreviewSizes() mà không bị biến dạng. Tôi mong đợi điều này để cắt xem trước bởi một số tiền trong chiều cao hoặc chiều rộng, nhưng điều này không liên quan đến tôi. Lý do tôi tìm cách làm điều này là vì một số máy ảnh android nhất định (ví dụ: máy ảnh mặt trước Samsung Galaxy SII) không trả lại bất kỳ bản xem trước nào có cùng tỷ lệ khung hình như màn hình và do đó cần được kéo dài và cắt bớt.Kết hợp xem trước máy ảnh với SurfaceView lớn hơn màn hình

Có thể phát triển đầy đủ chế độ xem trước máy ảnh cho chế độ xem lớn hơn kích thước hiển thị không? Có thể tăng SurfaceView lớn hơn kích thước pixel xem trước được trả về đơn giản bằng cách đặt tham số bố cục của chế độ xem bề mặt thành match_parent, nhưng điều này dẫn đến méo theo một số hướng và chỉ có thể cho đến khi xem trước lấp đầy màn hình. Điều này dường như chỉ ra rằng việc xem trước bên ngoài màn hình là không thể và phần cứng (hoặc OS) giới hạn hành vi đó.

another question về chủ đề, nhưng câu hỏi đó khẳng định không thể tạo SurfaceView lớn hơn kích thước màn hình, là sai, như tôi đã tìm thấy với ghi nhật ký. Tuy nhiên, những gì có vẻ là trường hợp đó là xem trước máy ảnh tuy nhiên không thể phát triển đến kích thước đầy đủ của một SurfaceView rất lớn.

Nỗ lực của tôi:

Tôi có một bố trí tương đối, bên trong nó một FrameLayout, và trong phạm vi mà tôi tạo ra một SurfaceView. Chiều rộng của toàn bộ bố cục tương đối được đặt bên dưới ở 635dp, bằng ~ gấp đôi kích thước màn hình của thiết bị. FrameLayout khớp với kích thước này và do đó SurfaceView (được thêm vào theo chương trình sau)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/camera_activity_layout" 
    android:layout_width="635dp" 
    android:layout_height="match_parent" > 

    <FrameLayout 
     android:id="@+id/camera_preview" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 
    </FrameLayout> 

</RelativeLayout> 

Sau đây là mã nhận và đặt kích thước xem trước. Ở đây tôi muốn mở rộng xem trước máy ảnh để lấp đầy toàn bộ FrameLayout (tăng gấp đôi chiều rộng màn hình). Chế độ xem hiển thị và phá hủy hoàn toàn bình thường nên tôi xóa mã không liên quan đến câu hỏi cụ thể này vì nó phân tâm khỏi câu hỏi cần thiết và nỗ lực của tôi dễ dàng và đơn giản là tăng lượt xem lên một số kích thước lớn hơn hiển thị.

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 

    ... 

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
     Camera.Parameters parameters = mCamera.getParameters(); 
     final DisplayMetrics dm = this.getResources().getDisplayMetrics(); 
      //getBestPreviewSize returns the best preview size, don't worry 
      //but some devices do not return one for all camera matching the aspect ratio 
     cameraSize = getBestPreviewSize(parameters, dm.heightPixels, dm.widthPixels); 

     if (cameraSize!=null) { 
      parameters.setPreviewSize(cameraSize.width, cameraSize.height); 
      mCamera.setParameters(parameters); 
     } 

     FrameLayout.LayoutParams frameParams = (FrameLayout.LayoutParams) this.getLayoutParams(); 

     frameParams.width = 800; //For argument's sake making this ~double the width of the display. Same result occurs if I use MATCH_PARENT 
     frameParams.height = LayoutParams.MATCH_PARENT; 
     this.setLayoutParams(frameParams); 

     try { 
      mCamera.setPreviewDisplay(mHolder); 
      mCamera.startPreview(); 

      Log.d("surfChange","W/H of CamPreview (child) is "+this.getWidth()+"/"+this.getHeight()+" while parent is "); 
      Log.d("surfChange","W/H of holder (child) is "+mHolder.getSurfaceFrame().width()+"/"+mHolder.getSurfaceFrame().height()+" while parent is "); 
     } catch (Exception e){ 
     } 
    } 
}; 

Tôi lo ngại rằng cách duy nhất để thành công trong nỗ lực này là bằng cách nào đó trả cho một bề mặt OpenGL, nhưng apparently này có thể là quá chậm trong đầy đủ màu sắc. Nó cũng là một nỗi đau nếu xem trước máy ảnh chỉ đơn giản có thể được kéo dài và cắt bớt.

Cảm ơn bạn trước bất kỳ nỗ lực nào trong giải pháp.

+0

Bạn có thể đăng mã ur oncreate(). hoặc nơi bạn gọi phương thức setcontentview() –

+0

Tại sao bạn tò mò về mã đó? Nó khá cơ bản và chỉ cần đặt chế độ xem nội dung cho xml mà tôi đã chia sẻ ở trên. –

+0

ok vì vậy tôi nghĩ rằng việc mở rộng chế độ xem ngoài trình quản lý cửa sổ là không thể, tôi cũng đang tìm kiếm phóng to một phần video nhưng sử dụng tất cả chế độ xem bề mặt và chế độ xem video tùy chỉnh mà tôi không nhận được, video không bị cắt ngoài kích thước –

Trả lời

12

Ok, tôi biết điều này rất muộn là câu trả lời nhưng có thể. Dưới đây là mã từ mẫu SDK Android. Để xem phần còn lại của mã để thực hiện tải xuống này khi mẫu sdk android và đi đến Samples/android-10(one I used, could try whichever you want to target)/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.java

class PreviewSurface extends ViewGroup implements SurfaceHolder.Callback { 
... 
@Override 
protected void onLayout(boolean changed, int l, int t, int r, int b) { 
    if (changed && getChildCount() > 0) { 
     final View child = getChildAt(0); 

     final int width = r - l; 
     final int height = b - t; 

     int previewWidth = width; 
     int previewHeight = height; 
     if (mPreviewSize != null) { 
      previewWidth = mPreviewSize.width; 
      previewHeight = mPreviewSize.height; 
     } 

     // Center the child SurfaceView within the parent. 
     if (width * previewHeight > height * previewWidth) { 
      final int scaledChildWidth = previewWidth * height/previewHeight; 
      child.layout((width - scaledChildWidth)/2, 0, 
        (width + scaledChildWidth)/2, height); 
     } else { 
      final int scaledChildHeight = previewHeight * width/previewWidth; 
      child.layout(0, (height - scaledChildHeight)/2, 
        width, (height + scaledChildHeight)/2); 
     } 
    } 
} 
} 

mã này được thiết kế để phù hợp với xem trước để kích thước nhỏ nhất (mà không mess lên tỷ lệ aspcect) và trung tâm để có các thanh màu đen ở kích thước khác. Nhưng nếu bạn lật > thành < thay vào đó bạn sẽ đạt được những gì bạn muốn. Ví dụ:

if (width * previewHeight < height * previewWidth) {... 
Các vấn đề liên quan