最近项目要求自定义相机,所以记录分享一下实现过程
第一步:首先是设置holder
mHolder = mDiagnosSurfaceview.getHolder();
mHolder.addCallback(new MySurfaceHolderCallback());
mHolder.setKeepScreenOn(true);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
第二步然后就是写MySurfaceHolderCallBack
public class MySurfaceHolderCallback implements SurfaceHolder.Callback
//自定义MySurfaceHolderCallback 实现 surfaceholder.callback 复写三个方法
//MySurfaceHolderCallback的第一个方法surfaceCreated的内容
mHolder = holder;//这个很重要是为了在返回桌面或者从别的类返回之后还可以看到预览界面,不然就会黑屏的
mCamera = Camera.open();
if (mCamera != null) {
Camera.Parameters parameters = mCamera.getParameters();
parameters.setJpegQuality(100);
//mHeightPixels,mWidthPixels两个是测量的不同手机的宽高,之前是写死的1920*1080
//结果在有些手机上面会出现黑屏的现象所以这一步很重要具体怎么获得的下面会给出代码
parameters.setPreviewSize(mHeightPixels, mWidthPixels);
parameters.setPictureFormat(ImageFormat.JPEG);
parameters.setPictureSize(mHeightPixels, mWidthPixels);
mCamera.setDisplayOrientation(90);
//设置自动对焦
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
mCamera.setParameters(parameters);
try {
mCamera.setPreviewDisplay(mHolder);
} catch (IOException e) {
e.printStackTrace();
}
mCamera.startPreview();
//MySurfaceHolderCallback的第二个方法surfaceChanged里面的内容
mHolder = holder;//这个方法也是在返回桌面或者从别的类返回之后还可以看到预览界面,不然就会黑屏的
//MySurfaceHolderCallback的第三个方法surfaceDestroyed里面的内容
//主要是释放资源
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
System.out.println("eee");
}
mHolder = null;
if (mHolder != null) {
mHolder = null;
System.out.println("rrr");
}
下面的代码是怎么获取屏幕的宽高
WindowManager wm = getWindowManager();
Display display = wm.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
//屏幕的宽
mWidthPixels = metrics.widthPixels;
//屏幕的高
mHeightPixels = metrics.heightPixels;
好了,预览的代码写完了,接下来是拍照了
在需要点击拍照的点击事件下面写如下方法
“`
private void startCemera() {
Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
Matrix matrix = new Matrix();
matrix.reset();
//又时候要求转换摄像头,会发现转到前置摄像头的时候显示的照片是倒着的,所以有这个判断前置就rotate
//270度,后置的rotate90度
if (isBackCamera) {
matrix.postRotate(90);
} else {
matrix.postRotate(270);
}
Bitmap bMapRotate = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
//不做如上处理,竖着拍照显示的照片是横向的,通过matrix对bitmap的处理照片正着拍显示的时候是正着的
//横着拍就是横着的
bitmap = bMapRotate;
mCamera.stopPreview();
String saveName = Environment.getExternalStorageDirectory().getAbsolutePath() + "/aaaa/" + System.currentTimeMillis() + ".jpg";
File file = new File(saveName);
if (!file.exists()) {
file.getParentFile().mkdirs();
}
//将图片写入文件路径为savename的文件里面
try {
FileOutputStream fout = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fout);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
bos.flush();
bos.close();
//跳转到展示图片的类 通过glide展示
//Glide.with(this).load(mFilepath).fitCenter().into(mShowIv);
Intent in = new Intent(DiagnosisBeginActivity.this, ShowPicActivity.class);
in.putExtra("filepath", saveName);
startActivity(in);
} catch (Exception e) {
e.printStackTrace();
}
}
};
mCamera.takePicture(null, null, pictureCallback);
}
好了,自定义相机基本步骤全部写完了,记得6.0动态权限的添加,我这里就不赘述了
第一次写博客,写的不好的地方大家多多指正,谢谢!