很多app都要求自定義一個相機,類似違章查詢拍照麦向,美圖相機之類的應(yīng)用都要求自定義相機瘟裸,網(wǎng)上的例子大多數(shù)我也看過,很多例子是有坑的诵竭,存在各種各樣的問題话告,常見的就是問題就是適配性很差兼搏,這里我分享一下我做的一個自定義相機,算是淺度實現(xiàn)吧沙郭,實現(xiàn)了拍照和保存和添加水印的功能佛呻,做過測試,三星S7病线,華為榮耀7吓著,oppoR9s,vivoY66都可以通過測試
截屏.jpg
好了下面直接上代碼吧送挑,關(guān)于坑點绑莺,會在代碼中注釋:
第一步,配置權(quán)限:
<!-- 相機硬件的權(quán)限 -->
<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三個方法中罢荡,里面把預(yù)覽及相機初始化的一些工作做了
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();
//相機支持的拍攝圖片尺寸赡突,拍照圖片尺寸小于等于屏幕尺寸,實現(xiàn)適配
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);
//設(shè)置尺寸以適配所有機型区赵,圖片尺寸小于等于屏幕尺寸惭缰,部分機型崩潰的問題得到了解決
mParameters.setJpegQuality(99); // 設(shè)置照片質(zhì)量
List<String> aa = mParameters.getSupportedFocusModes();
//設(shè)置對焦模式,低端機型可能不支持快速對焦笼才,當(dāng)然現(xiàn)在大部分機型支持漱受,但是也得適配啊
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中去實現(xiàn)拍照的操作:
//綁定surfaceView
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
mCameraSurPreview = new SurfacePreview(this);
preview.addView(mCameraSurPreview);
//拍照
mCameraSurPreview.takePicture(this);