2016-12-05 8 views
0

カメラの表面を含むプロジェクトを開始しました(画面上に画像のプレビューを表示するために使用されます)。これを実装する際には多くの問題がありますが、プレビューオリエンテーションに関する詳細やスタックの問題についてはスタックのトピックを検索していますが、プレビューオリエンテーションやスケマティックに関する良い結果は得られませんでしたまったく。理想的なsurfaceViewカメラの向きと比率(プレビューの伸びを避ける) - android

私がしたいのは、電話機が回転していても、同じ角度でプレビューを取得することです。そのため、ユーザーは常にそのような顔を見ることができます。

Example picture

あなたはどのように私はaswell portretや風景のビューの延伸プレビューを避けるために、自分のコードを変更することができ、私を提案してくださいすることができれば、私は喜んでいるだろう。私はあなたがあなたのプレビューに表示する特定の比率を選択する必要があなたのアプローチでは

public class CameraView extends SurfaceView implements SurfaceHolder.Callback { 


private SurfaceHolder mHolder; 
private Camera mCamera; 


public CameraView (Context context, Camera camera){ 
    super(context); 
    mCamera = camera; 
    mCamera.setDisplayOrientation(90); 


    //get the holder and set this class as the callback, so we can get camera data here 
    mHolder = getHolder(); 
    mHolder.addCallback(this); 
    //mHolder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL); 
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
} 

@Override 
public void surfaceCreated(SurfaceHolder surfaceHolder) { 
    try { 
     Camera.Parameters parameters = mCamera.getParameters(); 
     if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) { 
      parameters.set("orientation", "portrait"); 
      mCamera.setDisplayOrientation(90); 
      parameters.setRotation(90); 
     } 
     else { 
      // This is an undocumented although widely known feature 
      parameters.set("orientation", "landscape"); 
      // For Android 2.2 and above 
      mCamera.setDisplayOrientation(0); 
      // Uncomment for Android 2.0 and above 
      parameters.setRotation(0); 
     } 
     mCamera.setPreviewDisplay(surfaceHolder); 
     mCamera.startPreview(); 

    } catch (IOException e) { 
     // left blank for now 
    } 
} 

@Override 
public void surfaceDestroyed(SurfaceHolder surfaceHolder) { 
    this.getHolder().removeCallback(this); 
    mCamera.stopPreview(); 
    mCamera.release(); 
} 

@Override 
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, 
          int width, int height) { 

    try { 
     Camera.Parameters parameters = mCamera.getParameters(); 
     if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) { 
      parameters.set("orientation", "portrait"); 
      mCamera.setDisplayOrientation(90); 
      parameters.setRotation(90); 
      setCamera(mCamera); 
      mCamera.setPreviewDisplay(surfaceHolder); 
      mCamera.startPreview(); 
     } 
     else { 

      parameters.set("orientation", "landscape"); 
      mCamera.setDisplayOrientation(0); 
      parameters.setRotation(0); 
     } 
     setCamera(mCamera); 
     mCamera.setPreviewDisplay(surfaceHolder); 
     mCamera.startPreview(); 

    } catch (IOException e) { 

    } 
} 

public void setCamera(Camera camera){ 
    mCamera = camera; }    

答えて

0

の上に私のコードを考えattatchingてる

、これは画面サイズに基づいて異なる結果を生成します。

あなたは次のように、あなたがあなた自身のカメラのプレビューを定義することができます別のアプローチを検討する必要があります。

public class CameraSourcePreview extends ViewGroup { 



     private static final String TAG = "CameraSourcePreview"; 
     private Context mContext; 
     private SurfaceView mSurfaceView; 
     private boolean mStartRequested; 
     private boolean mSurfaceAvailable; 
     private CameraSource mCameraSource; 

     private GraphicOverlay mOverlay; 

     public CameraSourcePreview(Context context, AttributeSet attrs) { 
      super(context, attrs); 
      mContext = context; 
      mStartRequested = false; 
      mSurfaceAvailable = false; 

      mSurfaceView = new SurfaceView(context); 
      mSurfaceView.getHolder().addCallback(new SurfaceCallback()); 
      addView(mSurfaceView); 
     } 

     public void start(CameraSource cameraSource) throws IOException { 
      if (cameraSource == null) { 
       stop(); 
      } 

      mCameraSource = cameraSource; 

      if (mCameraSource != null) { 
       mStartRequested = true; 
       startIfReady(); 
      } 
     } 

     public void start(CameraSource cameraSource, GraphicOverlay overlay) throws IOException { 
      mOverlay = overlay; 
      start(cameraSource); 
     } 

     public void stop() { 
      if (mCameraSource != null) { 
       mCameraSource.stop(); 
      } 
     } 

     public void release() { 
      if (mCameraSource != null) { 
       mCameraSource.release(); 
       mCameraSource = null; 
      } 
     } 

     private void startIfReady() throws IOException { 
      if (mStartRequested && mSurfaceAvailable) { 
       mCameraSource.start(mSurfaceView.getHolder()); 
       if (mOverlay != null) { 
        Size size = mCameraSource.getPreviewSize(); 
        int min = Math.min(size.getWidth(), size.getHeight()); 
        int max = Math.max(size.getWidth(), size.getHeight()); 
        if (isPortraitMode()) { 
         // Swap width and height sizes when in portrait, since it will be rotated by 
         // 90 degrees 
         mOverlay.setCameraInfo(min, max, mCameraSource.getCameraFacing()); 
        } else { 
         mOverlay.setCameraInfo(max, min, mCameraSource.getCameraFacing()); 
        } 
        mOverlay.clear(); 
       } 
       mStartRequested = false; 
      } 
     } 

     private class SurfaceCallback implements SurfaceHolder.Callback { 
      @Override 
      public void surfaceCreated(SurfaceHolder surface) { 
       mSurfaceAvailable = true; 
       try { 
        startIfReady(); 
       } catch (IOException e) { 
        Log.e(TAG, "Could not start camera source.", e); 
       } 
      } 

      @Override 
      public void surfaceDestroyed(SurfaceHolder surface) { 
       mSurfaceAvailable = false; 
      } 

      @Override 
      public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
      } 
     } 

     @Override 
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 
      int previewWidth = 320; 
      int previewHeight = 240; 
      if (mCameraSource != null) { 
       Size size = mCameraSource.getPreviewSize(); 
       if (size != null) { 
        previewWidth = size.getWidth(); 
        previewHeight = size.getHeight(); 
       } 
      } 

      // Swap width and height sizes when in portrait, since it will be rotated 90 degrees 
      if (isPortraitMode()) { 
       int tmp = previewWidth; 
       previewWidth = previewHeight; 
       previewHeight = tmp; 
      } 

      final int viewWidth = right - left; 
      final int viewHeight = bottom - top; 

      int childWidth; 
      int childHeight; 
      int childXOffset = 0; 
      int childYOffset = 0; 
      float widthRatio = (float) viewWidth/(float) previewWidth; 
      float heightRatio = (float) viewHeight/(float) previewHeight; 

      // To fill the view with the camera preview, while also preserving the correct aspect ratio, 
      // it is usually necessary to slightly oversize the child and to crop off portions along one 
      // of the dimensions. We scale up based on the dimension requiring the most correction, and 
      // compute a crop offset for the other dimension. 
      if (widthRatio > heightRatio) { 
       childWidth = viewWidth; 
       childHeight = (int) ((float) previewHeight * widthRatio); 
       childYOffset = (childHeight - viewHeight)/2; 
      } else { 
       childWidth = (int) ((float) previewWidth * heightRatio); 
       childHeight = viewHeight; 
       childXOffset = (childWidth - viewWidth)/2; 
      } 

      for (int i = 0; i < getChildCount(); ++i) { 
       // One dimension will be cropped. We shift child over or up by this offset and adjust 
       // the size to maintain the proper aspect ratio. 
       getChildAt(i).layout(
         -1 * childXOffset, -1 * childYOffset, 
         childWidth - childXOffset, childHeight - childYOffset); 
      } 

      try { 
       startIfReady(); 
      } catch (IOException e) { 
       Log.e(TAG, "Could not start camera source.", e); 
      } 
     } 

     private boolean isPortraitMode() { 
      int orientation = mContext.getResources().getConfiguration().orientation; 
      if (orientation == Configuration.ORIENTATION_LANDSCAPE) { 
       return false; 
      } 
      if (orientation == Configuration.ORIENTATION_PORTRAIT) { 
       return true; 
      } 

      Log.d(TAG, "isPortraitMode returning false by default"); 
      return false; 
     } 

}

  • で:

    • は、カメラプレビュークラスを作成します。あなたのlayout.xmlはカスタムプレビューを追加します:

      <yourpackagename.CameraSourcePreview 
          android:id="@+id/preview" 
          android:layout_width="match_parent" 
          android:layout_height="match_parent"> 
      
      アクティビティクラス内

    • 、カメラソースメソッドを定義し、あなたがして)(のonCreateでメソッドを呼び出すことができます

    /** *カメラソースを開始または再起動し、それならば存在する。カメラソースが作成される前に、 *(カメラソースが作成される前にonResumeが呼び出されたなど)のカメラソースがまだ存在しない場合は、 *となります。 */

    private void startCameraSource() { 
        // check that the device has play services available. 
        int code = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(
          getApplicationContext()); 
        if (code != ConnectionResult.SUCCESS) { 
         Dialog dlg = 
           GoogleApiAvailability.getInstance().getErrorDialog(this, code, RC_HANDLE_GMS); 
         dlg.show(); 
        } 
    
        if (mCameraSource != null) { 
         try { 
          mPreview.start(mCameraSource, mGraphicOverlay); 
         } catch (IOException e) { 
          Log.e(TAG, "Unable to start camera source.", e); 
          mCameraSource.release(); 
          mCameraSource = null; 
         } 
        } 
    } 
    
    • は、以下を追加することを忘れないでください:

    /** * は、カメラを再起動します。

    @Override 
    protected void onResume() { 
        super.onResume(); 
    
        startCameraSource(); 
    } 
    

    /** * */

    は、カメラを停止します。 */

    @Override 
    protected void onPause() { 
        super.onPause(); 
        mPreview.stop(); 
    } 
    
    /** 
    * Releases the resources associated with the camera source, the associated detector, and the 
    * rest of the processing pipeline. 
    */ 
    
    
    @Override 
        protected void onDestroy() { 
         super.onDestroy(); 
         if (mCameraSource != null) { 
          mCameraSource.release(); 
         } 
        } 
    
  • +0

    いい例です。 – ArturS

    関連する問題