我平板上的camera保存的图片在电脑上可以正常显示,在平板上打开却是一张全黑色的图片,这是什么原因?
代码如下:
public class MainActivity extends AppCompatActivity implements View.OnClickListener,Camera.PreviewCallback {
private SurfaceView surfaceView;
private Button photograph;
private Button recording;
private Button switchs;
private int rotation;
private int shortSize;
private int longSize;
private Camera camera;
private Camera.CameraInfo cameraInfo;
private Camera.Parameters parameters;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
surfaceView = (SurfaceView) findViewById(R.id.camera_view);
photograph = (Button) findViewById(R.id.photograph);
recording = (Button) findViewById(R.id.recording);
switchs = (Button) findViewById(R.id.switchs);
photograph.setOnClickListener(this);
recording.setOnClickListener(this);
switchs.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.photograph:
if (camera == null) {
Toast.makeText(this, "请打开相机", Toast.LENGTH_SHORT).show();
return;
}
camera.takePicture(null,null, new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
new SavePicAsyncTask(MainActivity.this, cameraInfo.facing, data).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
});
break;
case R.id.recording:
break;
case R.id.switchs:
break;
}
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
int[] a = new int[2];
surfaceView.getLocationOnScreen(a);
shortSize = surfaceView.getHeight(); //横屏为宽度,竖屏为高度
longSize = surfaceView.getWidth();
rotation = getWindowManager().getDefaultDisplay().getRotation();
cameraInfo = new Camera.CameraInfo();
checkCameraPermission();
}
}
/*
1.申请相机权限----------------------------------------------------------------------------------------------------------------------------
*/
private void checkCameraPermission() {
//检查是否有相机权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
//没权限,请求权限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
1);
} else {
//有权限
Log.d("MainActivity","有权限");
getCameras(0); //0为后摄,1为前摄
}
}
//权限请求回调
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 1:
if (grantResults != null && grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//用户同意权限
getCameras(0); //0为后摄,1为前摄
} else {
// 权限被用户拒绝了,可以提示用户,关闭界面等等。
Toast.makeText(this, "拒绝权限,请去设置里面手动开启权限", Toast.LENGTH_SHORT).show();
}
break;
}
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
camera.addCallbackBuffer(data);
}
public void getCameras(int lens_facing) {
String[] cameras = new String[0];
String cameid = "0";
//先释放相机资源
releaseCamera();
//获取相机信息
if (cameraInfo == null) {
cameraInfo = new Camera.CameraInfo();
}
//获取相机个数
int cameraCount = Camera.getNumberOfCameras();
//由于不知道第几个是前置摄像头,遍历获取前置摄像头
for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
Camera.getCameraInfo(camIdx, cameraInfo);
if (cameraInfo.facing == lens_facing) {
//根据id打开相机
Log.d("MainActivity","相机id为"+camIdx);
camera = Camera.open(camIdx);
setPreview();
break;
}
}
}
public void setPreview() {
try {
//设置摄像头参数
parameters = camera.getParameters();
//设置预览大小
parameters.setPreviewSize(getBestSize().width, getBestSize().height);
//设置图片大小,拍照
parameters.setPictureSize(getBestSize().width, getBestSize().height);
//设置格式,所有的相机都支持 NV21格式
parameters.setPreviewFormat(ImageFormat.NV21);
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
//修改相机摄像头参数
camera.setParameters(parameters);
//修改相机预览方向
camera.setDisplayOrientation(adjustCameraOrientation());
//绑定预览视图
camera.setPreviewDisplay(surfaceView.getHolder());
//设置预览数据监听
camera.setPreviewCallbackWithBuffer(this);
//开始预览
camera.startPreview();
} catch (IOException e) {
}
}
/**
* 获取预览最佳尺寸
*/
private Camera.Size getBestSize() {
List<Camera.Size> sizes = parameters.getSupportedPreviewSizes();
Camera.Size bestSize = null;
float uiRatio = (float) longSize / shortSize;
float minRatio = uiRatio;
for (Camera.Size previewSize : sizes) {
float cameraRatio = (float) previewSize.width / previewSize.height;
//如果找不到比例相同的,找一个最近的,防止预览变形
float offset = Math.abs(cameraRatio - minRatio);
if (offset < minRatio) {
minRatio = offset;
bestSize = previewSize;
}
//比例相同
if (uiRatio == cameraRatio) {
bestSize = previewSize;
break;
}
}
return bestSize;
}
private int adjustCameraOrientation() {
//判断当前的横竖屏
int degress = 0;
//获取手机的方向
switch (rotation) {
case Surface.ROTATION_0:
degress = 0;
break;
case Surface.ROTATION_90:
degress = 90;
break;
case Surface.ROTATION_180:
degress = 180;
break;
case Surface.ROTATION_270:
degress = 270;
break;
}
int result = 0;
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
result = (cameraInfo.orientation - degress + 360) % 360;
} else if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (cameraInfo.orientation + degress) % 360;
result = (360 - result) % 360;
}
return result;
}
private void releaseCamera() {
if (camera != null) {
camera.stopPreview();
camera.stopFaceDetection();
camera.setPreviewCallback(null);
camera.release();
camera = null;
}
}
class SavePicAsyncTask extends AsyncTask<Void, Void, File> {
Context context;
int facing;
byte[] data;
public SavePicAsyncTask(Context context, int facing, byte[] data) {
this.context = context;
this.facing = facing;
this.data = data;
}
@Override
protected File doInBackground(Void... voids) {
//保存的文件
File picFile = null;
try {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
if (bitmap == null) {
return null;
}
//保存之前先调整方向
if (facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
Matrix matrix = new Matrix();
matrix.postRotate(90);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
} else {
Matrix matrix = new Matrix();
matrix.postRotate(270);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
// SD卡根目录
File dir = context.getExternalFilesDir("print");
if (!dir.exists()) {
dir.mkdirs();
}
picFile = new File(dir, System.currentTimeMillis() + ".JPEG");
FileOutputStream fos = new FileOutputStream(picFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.close();
bitmap.recycle();
return picFile;
} catch (Exception e) {
e.printStackTrace();
}
return picFile;
}
@Override
protected void onPostExecute(File file) {
super.onPostExecute(file);
if (file != null) {
Toast.makeText(context, "图片保存成功", Toast.LENGTH_SHORT).show();
camera.startPreview();
} else {
Toast.makeText(context, "图片保存失败", Toast.LENGTH_SHORT).show();
}
}
}
}