我第一次使用表面视图和表面支架,对两者都有非常粗略的了解,在surfaceview中的实时图像预览是倾斜和旋转的,在搜索时我发现我需要设置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)
对于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();
}
}