2016-05-25 11 views
4

私のプロジェクトでCamera 2 APIを実装しています。私はカメラのフルスクリーンプレビューのサイズを設定しTextureViewとコードのこれらの行を使用しています:Android Camera 2のプレビューサイズとデバイスのアスペクト比

StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); mPreviewSize = map.getOutputSizes(SurfaceTexture.class)[0];

これは最大プレビューサイズ、そのデバイスのサポートのようです。このサイズがすべてのデバイスで機能し、デバイスのアスペクト比が伸びずに収まるかどうかはわかりません。誰か知っていますか?

答えて

2

このアプローチが失敗する場合がありますが、なぜあなたの質問に完全な答えがありません。

は対照的に、私は最も確かに動作するバージョンを実装する方法については、適切なアプローチがあります。

Google API demos for the Camera 2を見ると、私はそれが収まることを確認するためにあなたに役立つはずであるいくつかのサンプルコードを見つけましたすべての画面には、正しいサイズ:

/** 
* Given {@code choices} of {@code Size}s supported by a camera, choose the smallest one that 
* is at least as large as the respective texture view size, and that is at most as large as the 
* respective max size, and whose aspect ratio matches with the specified value. If such size 
* doesn't exist, choose the largest one that is at most as large as the respective max size, 
* and whose aspect ratio matches with the specified value. 
* 
* @param choices   The list of sizes that the camera supports for the intended output 
*       class 
* @param textureViewWidth The width of the texture view relative to sensor coordinate 
* @param textureViewHeight The height of the texture view relative to sensor coordinate 
* @param maxWidth   The maximum width that can be chosen 
* @param maxHeight   The maximum height that can be chosen 
* @param aspectRatio  The aspect ratio 
* @return The optimal {@code Size}, or an arbitrary one if none were big enough 
*/ 
private static Size chooseOptimalSize(Size[] choices, int textureViewWidth, 
     int textureViewHeight, int maxWidth, int maxHeight, Size aspectRatio) { 

    // Collect the supported resolutions that are at least as big as the preview Surface 
    List<Size> bigEnough = new ArrayList<>(); 
    // Collect the supported resolutions that are smaller than the preview Surface 
    List<Size> notBigEnough = new ArrayList<>(); 
    int w = aspectRatio.getWidth(); 
    int h = aspectRatio.getHeight(); 
    for (Size option : choices) { 
     if (option.getWidth() <= maxWidth && option.getHeight() <= maxHeight && 
       option.getHeight() == option.getWidth() * h/w) { 
      if (option.getWidth() >= textureViewWidth && 
       option.getHeight() >= textureViewHeight) { 
       bigEnough.add(option); 
      } else { 
       notBigEnough.add(option); 
      } 
     } 
    } 

    // Pick the smallest of those big enough. If there is no one big enough, pick the 
    // largest of those not big enough. 
    if (bigEnough.size() > 0) { 
     return Collections.min(bigEnough, new CompareSizesByArea()); 
    } else if (notBigEnough.size() > 0) { 
     return Collections.max(notBigEnough, new CompareSizesByArea()); 
    } else { 
     Log.e(TAG, "Couldn't find any suitable preview size"); 
     return choices[0]; 
    } 
} 

Source

はまた、あなたが適切なimplemenのための全体Camera2BasicFragment.javaAutoFitTextureView.javaクラスを見てみる必要があります。

+0

私はいくつかのデバイスを持っていますテストのために、Googleのサンプルを使用しましたが、一部のデバイスでうまく動作しません。カメラのプレビューはまだフルスクリーンで拡大されています。しかし、私が '' 'map.getOutputSizes(SurfaceTexture.class)[0]' 'を使うと、すべてのデバイスで完全に動作します。 – TrungNVT

+0

@ TrungNVTしかし、あなたはフルスクリーンプレビューを取得する必要はありません..右? –

6

カメラの解像度、テクスチャ表示とデバイスの表示寸法が同じでない場合は、寸法を調整する必要があります。そのためには、TextureViewをFrameLayoutの中に入れてください。以下のコードは、さまざまなディスプレイ解像度のすべてのデバイスに適用されます。

フルスクリーンでプレビューする場合は、表示ディメンションを使用してください。int DSI_heightint DSI_widthグローバル変数。

DisplayMetrics displayMetrics = new DisplayMetrics(); 
    getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); 
    DSI_height = displayMetrics.heightPixels; 
    DSI_width = displayMetrics.widthPixels; 

カメラ2 APIからあなたに必要な解像度を選択し、Size imageDimensionに割り当て、グローバルprivate Size imageDimensionを取り、

setAspectRatioTextureView(imageDimension.getHeight(),imageDimension.getWidth()); 

を使用して、論理の下に使用

private void setAspectRatioTextureView(int ResolutionWidth , int ResolutionHeight) 
    { 
     if(ResolutionWidth > ResolutionHeight){ 
      int newWidth = DSI_width; 
      int newHeight = ((DSI_width * ResolutionWidth)/ResolutionHeight); 
      updateTextureViewSize(newWidth,newHeight); 

     }else { 
      int newWidth = DSI_width; 
      int newHeight = ((DSI_width * ResolutionHeight)/ResolutionWidth); 
      updateTextureViewSize(newWidth,newHeight); 
     } 

    } 

    private void updateTextureViewSize(int viewWidth, int viewHeight) { 
     Log.d(TAG, "TextureView Width : " + viewWidth + " TextureView Height : " + viewHeight); 
     textureView.setLayoutParams(new FrameLayout.LayoutParams(viewWidth, viewHeight)); 
    } 
+0

素晴らしいです! –

+1

私はこの同じロジックを自分のアプリケーションに実装しました。あなたはここでそれをチェックすることができます:https://play.google.com/store/apps/details?id=ronakpatel1311.androidcameraapi2 –

+0

全体のコードを投稿してください。私は 'setAspectRatioTextureView'を呼び出す場所を理解していません。 – iMDroid

2

変更AutoFitTextureView.javaファイルや設定値などの以下:

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    int width = MeasureSpec.getSize(widthMeasureSpec); 
    int height = MeasureSpec.getSize(heightMeasureSpec); 

    if (0 == mRatioWidth || 0 == mRatioHeight) { 
     setMeasuredDimension(width, height); 
    } else { 
     if (width < height * mRatioWidth/mRatioHeight) { 
      setMeasuredDimension(width, height); 
      Log.d("rlijeolid1",String.valueOf(width)+"\t"+String.valueOf(height)); 
     } else { 
      setMeasuredDimension(width , height); 
      Log.d("rlijeolid2",String.valueOf(height * mRatioWidth/mRatioHeight)+"\t"+String.valueOf(height)); 
     } 
    } 
} 
+0

もしあなたがこれを行うことができればテキスト私はthnxを解決します.. –

2

私は別のアプローチでこの問題を解決しました。私は、画面の幅と高さを取得し、プレビューが画面全体を満たし、アスペクト比を維持するために必要な幅や高さを計算します。それは歪みのない私のためにかなりうまくいく。

クラスのメンバ変数を追加します。

public DisplayMetrics mMetrics = new DisplayMetrics(); 

onMeasureとして、次を使用します。すべてのフィードバックが大幅に高く評価されて

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    int width = MeasureSpec.getSize(widthMeasureSpec); 
    int height = MeasureSpec.getSize(heightMeasureSpec); 
    if (0 == mRatioWidth || 0 == mRatioHeight) { 
     setMeasuredDimension(width, height); 
    } else { 
     WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); 
     windowManager.getDefaultDisplay().getMetrics(mMetrics); 
     double ratio = (double)mRatioWidth/(double)mRatioHeight; 
     double invertedRatio = (double)mRatioHeight/(double)mRatioWidth; 
     double portraitHeight = width * invertedRatio; 
     double portraitWidth = width * (mMetrics.heightPixels/portraitHeight); 
     double landscapeWidth = height * ratio; 
     double landscapeHeight = (mMetrics.widthPixels/landscapeWidth) * height; 

     if (width < height * mRatioWidth/mRatioHeight) { 
      setMeasuredDimension((int)portraitWidth, mMetrics.heightPixels); 
     } else { 
      setMeasuredDimension(mMetrics.widthPixels, (int)landscapeHeight); 
     } 
    } 
} 

;)

ベストM

+0

私は恐れて、それは私のためには動作しません – FabioC

関連する問題