很多app都要求自定义一个相机,类似违章查询拍照,美图相机之类的应用都要求自定义相机,网上的例子大多数我也看过,很多例子是有坑的,存在各种各样的问题,常见的就是问题就是适配性很差,这里我分享一下我做的一个自定义相机,算是浅度实现吧,实现了拍照和保存和添加水印的功能,做过测试,三星S7,华为荣耀7,oppoR9s,vivoY66都可以通过测试
好了下面直接上代码吧,关于坑点,会在代码中注释:
第一步,配置权限:
<!-- 相机硬件的权限 -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
第二步,重写一个surfaceview,并在onSrfacexxxx三个方法中,里面把预览及相机初始化的一些工作做了
public void surfaceCreated(SurfaceHolder holder) {
Log.d(TAG, "surfaceCreated() is called");
try {
mCamera = Camera.open(0);
mCamera.setDisplayOrientation(90);
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Log.d(TAG, "surfaceChanged() is called");
try {
mCamera.autoFocus(new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
isSuccess = success;
initCamera();
mCamera.cancelAutoFocus();
mCamera.startPreview();
}
});
} catch (Exception e) {
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
private void initCamera() {
mParameters = mCamera.getParameters();
mParameters.setPictureFormat(ImageFormat.JPEG);
List<Camera.Size> pictureSizes = mParameters.getSupportedPictureSizes();
Camera.Size picSize = null;
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int screenWidth = display.getWidth();
int screenHeight = display.getHeight();
//相机支持的拍摄图片尺寸,拍照图片尺寸小于等于屏幕尺寸,实现适配
if (pictureSizes.size() > 1) {
for (Camera.Size size2 : pictureSizes) {
System.out.println("initCamera:" + size2.width + size2.height);
if (size2.width * size2.height <= screenWidth * screenHeight) {
if (picSize == null) {
picSize = size2;
} else {
if ((size2.width * size2.height) > (picSize.width * picSize.height)) {
picSize = size2;
}
}
}
}
} else {
picSize = pictureSizes.get(0);
}
mParameters.setPictureSize(picSize.width, picSize.height);
//设置尺寸以适配所有机型,图片尺寸小于等于屏幕尺寸,部分机型崩溃的问题得到了解决
mParameters.setJpegQuality(99); // 设置照片质量
List<String> aa = mParameters.getSupportedFocusModes();
//设置对焦模式,低端机型可能不支持快速对焦,当然现在大部分机型支持,但是也得适配啊
if (aa.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
mParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);//快速对焦
} else {
mParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
}
try {
mCamera.setParameters(mParameters);
mCamera.startPreview();
} catch (Exception e) {
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
if (mCamera != null) {
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
Log.d(TAG, "surfaceDestroyed() is called");
}
//拍照
public void takePicture(Camera.PictureCallback imageCallback) {
Log.d(TAG, "takePicture: " + isSuccess);
if (isSuccess) {
mCamera.takePicture(null, null, imageCallback);
} else {//如果不成功则重试对焦,否则拍出的照片可能糊
initCamera();
mCamera.cancelAutoFocus();
mCamera.takePicture(null, null, imageCallback);
}
}
}
第三步,在Activity中去实现拍照的操作:
//绑定surfaceView
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
mCameraSurPreview = new SurfacePreview(this);
preview.addView(mCameraSurPreview);
//拍照
mCameraSurPreview.takePicture(this);