实现SurfaceHolder.Callback , PictureCallback接口
预览service
/**
* 实例化按件
*/
private void findView() {
cameraView = (SurfaceView) this.findViewById(R.id.sfv_camera_view);
cameraView.setFocusable(true);
cameraView.setFocusableInTouchMode(true);
cameraView.setClickable(true);
cameraView.setOnClickListener(this);
surfaceHolder = cameraView.getHolder();
// 推送类型的surfaceView,缓冲区由Camera类来管理
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// 设置回调函数
surfaceHolder.addCallback(this);
}
/***********************************************/
@Override
public void surfaceCreated(SurfaceHolder holder) {
// 取得 camera对象
camera = Camera.open();
try {
// 设置camera对象的参数
// 设置camera对象采用纵向方向
Parameters parameters = camera.getParameters();
// 设置闪光灯模式
// 修改效果
// 列出常用效果:none mono negative sepia
// 类似的常量还有抗条带(antibanding) 闪光灯(flash mode)聚焦模式(focus mode)情景模式(scen
// mode) 白平衡(white balance)
List<String> colorEffects = parameters.getSupportedColorEffects();
Iterator<String> cei = colorEffects.iterator();
while (cei.hasNext()) {
String currentEffect = cei.next();
Log.i("tag", "checking:" + currentEffect);
// 使用过渡爆光
if (currentEffect.equals(Camera.Parameters.EFFECT_SOLARIZE)) {
Log.i("tag", "using SOLARIZE");
parameters.setColorEffect(Camera.Parameters.EFFECT_SOLARIZE);
break;
}
}
// 检查当前屏幕的方向
if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
// 一个未文档化的特性
parameters.set("orientation", "portrait");
// 对于2.2以上的版本
camera.setDisplayOrientation(90);
} else {
parameters.set("orientation", "landscape");
camera.setDisplayOrientation(0);
}
// 设置预览大小,接近但不超过一对常量的大小
/* int bestWidth = 0;
int bestHeight = 0;
List<Size> previewSize = parameters.getSupportedPreviewSizes();
if (previewSize.size() > 1) {
Iterator<Size> iterator = previewSize.iterator();
while (iterator.hasNext()) {
Size cameraSize = iterator.next();
Log.i("tag", "checking:" + cameraSize.width + " x " + cameraSize.height);
if (cameraSize.width > bestWidth && cameraSize.width <= LARGEST_WIDTH && cameraSize.height > bestHeight && cameraSize.height <= LARGEST_HEIGHT) {
bestHeight = cameraSize.height;
bestWidth = cameraSize.width;
cameraView.setLayoutParams(new LinearLayout.LayoutParams(bestWidth, bestHeight));
}
}
}
if (bestHeight != 0 && bestWidth != 0) {
Log.i("tag", "Using :" + bestWidth + " x " + bestHeight);
parameters.setPreviewSize(bestWidth, bestHeight);
}*/
camera.setParameters(parameters);
// 设置预览
camera.setPreviewDisplay(surfaceHolder);
} catch (IOException e) {
Log.i("tag", e.toString());
// 释放camera对象
camera.release();
}
// 启动摄像头预览
// 此时的预览图像会逆时针旋转90度,原因是camera对象假定方向是水平 或是横向模式
// 最简单的修复方法是使活动以横向模式显示
// setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
camera.startPreview();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// 停止预览
camera.stopPreview();
// 释放camera对象
camera.release();
}
/**
* 捕获和保存图像PictureCallback
*
* 其他的回调方法
*
* 1 PreviewCallback 当存在预览帧时调用
*
* 三种使用方法:
*
* setPreviewCallback 在屏幕上显不一个新的预览帖时调用onPictureFream
*
* setOneShotPreviewCallback 当下预览图像可用时调用
*
* setPreviewCallbackWithBuffer 指定一个字节数组作为缓冲区,用于预览图像
*
* 2 AutoFocusCallback 完成一个自动聚焦是调用
*
* 3 ErrorCallback 发生一个错误时调用
*
* 4 OnZoomChangeListener 放大/缩小时调用
*
* 5 ShutterCallback 当捕获图像时调用
*
* @data 图像数据的字节数组
* @camera camera的对象引用
*/
@Override
public void onPictureTaken(byte[] data, Camera camera) {
// 保存相片
Uri imageFileUri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, new ContentValues());
try {
OutputStream imageFileOS = getContentResolver().openOutputStream(imageFileUri);
imageFileOS.write(data);
imageFileOS.flush();
imageFileOS.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// 可以理新元数据
ContentValues contentValues = new ContentValues(3);
contentValues.put(Media.DISPLAY_NAME, "this is a test title");
contentValues.put(Media.DESCRIPTION, "this is a test description");
getContentResolver().update(imageFileUri, contentValues, null, null);
}
/**
* 重写点击事件
*/
@Override
public void onClick(View v) {
camera.takePicture(null, null, this);
}