2016-10-29 258 views
0

它是我第一次使用表面視圖和表面持有人與兩個非常粗糙的知識,表面視圖中的實時圖像預覽是傾斜和旋轉,搜索我發現我需要設置CameraParameter但我能理解它是如何工作的,也沒有任何指導,瞭解Camera2 API相機傾斜和旋轉

public class CamActivity extends AppCompatActivity implements SurfaceHolder.Callback{ 

Camera mCamera; 
SurfaceView surfaceView; 
private SurfaceHolder mHolder; 
FloatingActionButton cam; 
private static final int pRequestCode = 5002; 
private static final String[] mPermissions = {Manifest.permission.CAMERA, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE}; 


@Override 
protected void onCreate(@Nullable Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.cam_layout); 
    checkCameraHardware(); 
    checkPermissions(); 


    View decorView = getWindow().getDecorView(); 
    int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN; 
    decorView.setSystemUiVisibility(uiOptions); 

    surfaceView = (SurfaceView) findViewById(R.id.camera_preview); 
    mHolder = surfaceView.getHolder(); 
    mHolder.addCallback(this); 
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    cam = (FloatingActionButton) findViewById(R.id.fabCamera); 
    cam.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
        mCamera.takePicture(null, null, mPicture); 
       } 
      } 
    ); 
} 

private boolean checkCameraHardware() { 
    if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) { 
     // this device has a camera 
     return true; 
    } else { 
     // no camera on this device 
     return false; 
    } 
} 

private void checkPermissions() { 
    if (ContextCompat.checkSelfPermission(this, mPermissions[0]) != PackageManager.PERMISSION_GRANTED 
      ||ContextCompat.checkSelfPermission(this, mPermissions[1]) != PackageManager.PERMISSION_GRANTED 
      ||ContextCompat.checkSelfPermission(this, mPermissions[2]) != PackageManager.PERMISSION_GRANTED 
      ||ContextCompat.checkSelfPermission(this, mPermissions[3]) != PackageManager.PERMISSION_GRANTED) { 
     ActivityCompat.requestPermissions(this, mPermissions, pRequestCode); 
    } 
} 

@Override 
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 
    switch (requestCode) { 
     case pRequestCode: { 
      // If request is cancelled, the result arrays are empty. 
      if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
       Toast.makeText(this,"Camera Allowed",Toast.LENGTH_SHORT).show(); 
      } else { 
       Toast.makeText(this,"Camera Denied",Toast.LENGTH_SHORT).show(); 
      } 
      if (grantResults.length > 0 && grantResults[1] == PackageManager.PERMISSION_GRANTED) { 
       Toast.makeText(this,"Location Allowed",Toast.LENGTH_SHORT).show(); 
      } else { 
       Toast.makeText(this,"Location Denied",Toast.LENGTH_SHORT).show(); 
      } 
      if (grantResults.length > 0 && grantResults[2] == PackageManager.PERMISSION_GRANTED) { 
       Toast.makeText(this,"Microphone Allowed",Toast.LENGTH_SHORT).show(); 
      } else { 
       Toast.makeText(this,"Microphone Denied",Toast.LENGTH_SHORT).show(); 
      } 
      if (grantResults.length > 0 && grantResults[3] == PackageManager.PERMISSION_GRANTED) { 
       Toast.makeText(this,"Storage Allowed",Toast.LENGTH_SHORT).show(); 
      } else { 
       Toast.makeText(this,"Storage Denied",Toast.LENGTH_SHORT).show(); 
      } 
      return; 
     } 
    } 
} 

@Override 
public void surfaceCreated(SurfaceHolder holder) { 
    try { 
     mCamera = Camera.open(); 
    } 
    catch (Exception e){ 
    } 

    Camera.Parameters parameters = mCamera.getParameters(); 
    parameters.set("orientation", "portrait"); 
    mCamera.setParameters(parameters); 

    try { 
     mCamera.setPreviewDisplay(mHolder); 
     mCamera.startPreview(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

@Override 
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
    if (mHolder.getSurface() == null){ 
     // preview surface does not exist 
     return; 
    } 
    try { 
     mCamera.stopPreview(); 
    } catch (Exception e){ 
    } 

    try { 
     mCamera.setPreviewDisplay(mHolder); 
     mCamera.startPreview(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

@Override 
public void surfaceDestroyed(SurfaceHolder holder) { 
    mCamera.stopPreview(); 
    mCamera.release(); 
    mCamera = null; 
} 

private Camera.PictureCallback mPicture = new Camera.PictureCallback() { 

    @Override 
    public void onPictureTaken(byte[] data, Camera camera) { 

     File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE); 
     if (pictureFile == null){ 
      Log.d("", "Error creating media file, check storage permissions: "); 
      return; 
     } 

     try { 
      FileOutputStream fos = new FileOutputStream(pictureFile); 
      fos.write(data); 
      fos.close(); 
     } catch (FileNotFoundException e) { 
      Log.d("", "File not found: " + e.getMessage()); 
     } catch (IOException e) { 
      Log.d("", "Error accessing file: " + e.getMessage()); 
     } 
    } 
}; 

private static File getOutputMediaFile(int type){ 
    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyCameraApp"); 
    if (! mediaStorageDir.exists()){ 
     if (! mediaStorageDir.mkdirs()){ 
      Log.d("MyCameraApp", "failed to create directory"); 
      return null; 
     } 
    } 
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
    File mediaFile; 
    if (type == MEDIA_TYPE_IMAGE){ 
     mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_"+ timeStamp + ".jpg"); 
    } else if(type == MEDIA_TYPE_VIDEO) { 
     mediaFile = new File(mediaStorageDir.getPath() + File.separator + "VID_"+ timeStamp + ".mp4"); 
    } else { 
     return null; 
    } 
    return mediaFile; 
} 

}

+0

集「方向」 =「肖像」作品上的一些設備,但是這不是配置預覽表面的標準方法。 –

+0

如果「傾斜」意味着屏幕上物體的縱橫比錯誤,只需根據佈局中的表面尺寸設置相機預覽尺寸即可。 –

回答

0

對於Camera2 API,你可以在Android Studio或GitHub上查看Android的代碼示例。

您可以像這樣解決surfaceCreated()中的相機預覽旋轉和寬高比。請注意,你必須正確地與例外處理:

@Override 
public void surfaceCreated(SurfaceHolder holder) { 

    // You need to open the camera in a 
    // different manner so you can obtain some info from it 
    int numberOfCameras = Camera.getNumberOfCameras(); 
    Camera.CameraInfo info = new Camera.CameraInfo(); 
    mCamera = null; 
    for (int i = 0; i < numberOfCameras; i++) { 
     Camera.getCameraInfo(i, info); 
     // Open a back camera 
     if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) { 
      try { 
       mCamera = Camera.open(i); 
       break; 
      } catch (RuntimeException e) { 
       // Could not open camera 
      } 
     } 
    } 
    if (mCamera == null) { 
     // No camera found 
    } 

    Camera.Parameters parameters = mCamera.getParameters(); 

    // Rotate display 
    // Code from here: 
    // https://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation(int) 
    int rotation = activity.getWindowManager().getDefaultDisplay() 
     .getRotation(); 
    int degrees = 0; 
    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 (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 
     result = (info.orientation + degrees) % 360; 
     result = (360 - result) % 360; // compensate the mirror 
    } else { // back-facing 
     result = (info.orientation - degrees + 360) % 360; 
    } 
    mCamera.setDisplayOrientation(result); 

    Camera.Size size = parameters.getPreviewSize(); 
    // You'll probably want to set the preview 
    // width and height to match the preview size 
    // aspect ratio that you can obtain by: 
    // (double) size.width/(double) size.height 
    // 
    // Note that if the int result above modulo 180 
    // equals 90, you'll have to exchange width for height 
    // and vice versa. 

    try { 
     mCamera.setPreviewDisplay(mHolder); 
     mCamera.startPreview(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
}