一、Surfaceview的使用
surfaceView的使用主要有三步:继承SurfaceView;获取SurfaceViewHolder;应用Holder更新展示内容。Surfaceview的应用有常用类型及数据展示的Demo。
拍照功能实现思路:
<span style="font-size:18px;">1,依据布局,获取Surfaceview对象;
2,获取Holder对象并设置属性;
3,绑定SurfaceHolder.Callback回调接口;
4,回调接口的surfaceCreated方法中设置Camera并设置对应属性;
5,设置拍照点击事件,在监听事件中绑定Camera.PictureCallback回调监听;
6,PictureCallback监听中依据回调数据,进行结果保存。【保存照片并展示】</span>
二、实现拍照功能
activity_take_pic.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<SurfaceView
android:id="@+id/surfaceView_2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible" />
<ImageView
android:id="@+id/pic_pre_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
<Button
android:id="@+id/take_pic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:background="@mipmap/camera_canon"
android:text="拍照" />
</FrameLayout>
TakePictureActivity.java主类实现:
public class TakePictureActivity extends Activity {
/**
* 图片预览及展示
*/
private SurfaceView surfaceView;
/**
* 拍照
*/
private Button takePic;
/**
* 图片展示
*/
private ImageView preViewPic;
/**
* 调用系统相机
*/
private Camera camera;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_take_pic);
/**
* 窗口布满全局
*/
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
initView();
initListener();
}
/**
* 初始化View
*/
private void initView() {
surfaceView = (SurfaceView) findViewById(R.id.surfaceView_2);
takePic = (Button) findViewById(R.id.take_pic);
preViewPic = (ImageView) findViewById(R.id.pic_pre_view);
}
/**
* 初始化监听器
*/
private void initListener() {
SurfaceHolder holder = surfaceView.getHolder();
holder.setFixedSize(176, 155);
holder.setKeepScreenOn(true);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
holder.addCallback(new TakePictureSurfaceCallback());
takePic.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (camera != null) {
camera.takePicture(null, null, new TakePictureCallback());
}
}
});
}
private final class TakePictureSurfaceCallback implements SurfaceHolder.Callback {
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
camera = Camera.open();
if (camera == null) {
int cametacount = Camera.getNumberOfCameras();
camera = Camera.open(cametacount - 1);
}
Camera.Parameters params = camera.getParameters();
params.setJpegQuality(80);//照片质量
params.setPictureSize(1024, 768);//图片分辨率
params.setPreviewFrameRate(5);//预览帧率
camera.setDisplayOrientation(90);
/**
* 设置预显示
*/
<span style="color:#FF0000;">// camera.setPreviewDisplay(surfaceView.getHolder());
camera.setPreviewDisplay(holder);</span>
camera.setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
}
});
/**
* 开启预览
*/
camera.startPreview();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (camera != null) {
camera.release();
camera = null;
}
}
}
private final class TakePictureCallback implements Camera.PictureCallback {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
ByteArrayOutputStream os = new ByteArrayOutputStream(data.length);
byte[] tempData = os.toByteArray();
if (tempData != null && tempData.length > 0) {
Bitmap bitmap = BitmapFactory.decodeByteArray(tempData, 0, tempData.length);
preViewPic.setVisibility(View.VISIBLE);
surfaceView.setVisibility(View.GONE);
preViewPic.setImageBitmap(bitmap);
}
}
}
}
展示效果:
三、细节注意
1,SurfaceHolder.Callback的surfaceCreated方法中,holder使用传参即可;
2,Camera在使用后必须camera.release();释放相机资源。
您也可以看看:Surfaceview的应用~_~
代码前行的路上还有些许枯燥,我愿意倾听您的声音,也希望您的帮助能更多的优化自己。我还没有爱上这个行业,我尽可能的保持一种好习惯,我相信能力增强的路上给我更多绚丽,一定会让我爱上这个行业的。现在的我只是及格,在及格边上徘徊。我处于迷茫中,暂时找不到出口 #_# || 就多积累点。。。。。
“真正的勤奋,不是被迫的机械重复劳动,也不是自我感动式的摧残健康,更不是因为
拖延症导致的最后一刻效率爆发。它来自于一个人内心深处,对与那些无法获得即刻回
报的事情,依然能够保持十年如一的热情与专注。”