Android自定义照相机倒计时拍照
自定义拍照会用到SurfaceView控件显示照片的预览区域,以下是布局文件:
两个TextView是用来显示提示信息和倒计时的秒数的
相关教程:Android开发从相机或相册获取图片裁剪
Android启动相机拍照并返回图片
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#266194" android:orientation="vertical" tools:context=".TestActivity"> <SurfaceView android:id="@+id/surfaceView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerInParent="true"/> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="请调整位置到此区域" android:textColor="#ff0000" android:textSize="32sp"/> <TextView android:id="@+id/tv_time" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="10dp" android:gravity="center_horizontal" android:textColor="#266194" android:textSize="32sp"/> </LinearLayout> </RelativeLayout>
接下来是mainActivity中的具体实现以及详细注释:
packagecom.dhsr.pujiejia.ui;
importjava.io.File;
importjava.io.FileOutputStream;
importjava.text.SimpleDateFormat;
importjava.util.Date;
importandroid.annotation.SuppressLint;
importandroid.app.Activity;
importandroid.content.Context;
importandroid.content.Intent;
importandroid.content.res.Configuration;
importandroid.graphics.Bitmap;
importandroid.graphics.BitmapFactory;
importandroid.graphics.PixelFormat;
importandroid.hardware.Camera;
importandroid.hardware.Camera.CameraInfo;
importandroid.os.Bundle;
importandroid.os.Environment;
importandroid.os.Handler;
importandroid.view.SurfaceHolder;
importandroid.view.SurfaceView;
importandroid.view.Window;
importandroid.view.WindowManager;
importandroid.widget.TextView;
importcom.example.pujiejiaapp.R;
@SuppressLint({"NewApi","SdCardPath"})
publicclassCameraActivityextendsActivityimplementsRunnable{
//预览图片范围
privateSurfaceViewsurfaceView;
privateTextViewtv_time;
//倒计时拍摄
privateintcameratime=4;
privateCameracamera;
privatebooleanpreview=false;
//文件名字
privateStringfilename;
//文件名字的带的时间戳
privateStringtimeString;
//格式化时间
privateSimpleDateFormatdateFormat;
//日期对象
privateDatedate;
//控制线程
booleanstopThread=false;
privateFilefile;
Stringphoto;
privateHandlermHandler=newHandler(){
publicvoidhandleMessage(android.os.Messagemsg){
intwhat=msg.what;
switch(what){
case222:
tv_time.setText(""+cameratime);
if("0".equals(tv_time.getText().toString())){
tv_time.setText("拍摄成功!");
takePhoto();
}
break;
}
};
};
@Override
protectedvoidonCreate(BundlesavedInstanceState){
//TODOAuto-generatedmethodstub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
CameraActivity.this.setFinishOnTouchOutside(false);
//初始化数据
findView();
surfaceView.getHolder().addCallback(newSufaceListener());
/*下面设置Surface不维护自己的缓冲区,而是等待屏幕的渲染引擎将内容推送到用户面前*/
surfaceView.getHolder()
.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
surfaceView.getHolder().setFixedSize(200,200);//设置分辨率
}
@Override
protectedvoidonStart(){
//TODOAuto-generatedmethodstub
super.onStart();
//开启线程
newThread(this).start();
}
privatefinalclassSufaceListenerimplementsSurfaceHolder.Callback{
/**
*surface改变
*/
@Override
publicvoidsurfaceChanged(SurfaceHolderholder,intformat,intwidth,
intheight){
}
/**
*surface创建
*/
@Override
publicvoidsurfaceCreated(SurfaceHolderholder){
try{
for(inti=0;i<Camera.getNumberOfCameras();i++){
CameraInfoinfo=newCameraInfo();
Camera.getCameraInfo(i,info);
//调用系统的前置摄像头
if(info.facing==CameraInfo.CAMERA_FACING_FRONT){
camera=Camera.open(i);
}
}
Camera.Parametersparameters=camera.getParameters();
/*每秒从摄像头捕获5帧画面,*/
parameters.setPreviewFrameRate(5);
/*设置照片的输出格式:jpg*/
parameters.setPictureFormat(PixelFormat.JPEG);
/*照片质量*/
parameters.set("jpeg-quality",85);
WindowManagerwm=(WindowManager)getSystemService(Context.WINDOW_SERVICE);
camera.setParameters(parameters);
camera.setPreviewDisplay(surfaceView.getHolder());//通过SurfaceView显示取景画面
camera.startPreview();
preview=true;
}catch(Exceptione){
}
}
/**
*surface销毁
*/
@Override
publicvoidsurfaceDestroyed(SurfaceHolderholder){
if(camera!=null){
if(preview)
camera.stopPreview();
camera.release();
camera=null;
}
}
}
/**
*拍摄照片
*/
privatevoidtakePhoto(){
//执行拍照效果
camera.takePicture(null,null,newCamera.PictureCallback(){
@Override
publicvoidonPictureTaken(byte[]data,Cameracamera){
try{
Bitmapbitmap=BitmapFactory.decodeByteArray(data,0,
data.length);
timeString=formatDate();
//保存到data/data目录自定义文件夹下
filename="/data/data/com.example.pujiejiaapp/images/"
+timeString+".jpg";
Filefile=newFile(filename);
booleancreateNewFile=file.createNewFile()
System.out.println("创建文件夹成功没有"+createNewFile);
System.out.println(file);
FileOutputStreamoutStream=newFileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG,60,outStream);
outStream.flush();
outStream.close();
//重新浏览
camera.stopPreview();
camera.startPreview();
preview=true;
}catch(Exceptione){
e.printStackTrace();
}finally{
}
}
});
}
@Override
publicvoidrun(){
while(!stopThread){
try{
//按秒数倒计时
Thread.sleep(1000);
}catch(InterruptedExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
cameratime--;
mHandler.sendEmptyMessage(222);
if(cameratime<=0){
break;
}
}
}
//初始化数据
privatevoidfindView(){
surfaceView=(SurfaceView)this.findViewById(R.id.surfaceView);
tv_time=(TextView)findViewById(R.id.tv_time);
}
//格式化系统的时间
publicStringformatDate(){
date=newDate(System.currentTimeMillis());
//日期格式
dateFormat=newSimpleDateFormat("'IMG'_yyyyMMddHHmmss");
returndateFormat.format(date);
}
@Override
protectedvoidonDestroy(){
//TODOAuto-generatedmethodstub
//线程已关闭
super.onDestroy();
stopThread=true;
}
}
核心代码详解:
1.创建SurfaceView时,surfaceCreated()方法中
for(inti=0;i<Camera.getNumberOfCameras();i++){
CameraInfoinfo=newCameraInfo();
Camera.getCameraInfo(i,info);
//调用系统的前置摄像头
if(info.facing==CameraInfo.CAMERA_FACING_FRONT){
camera=Camera.open(i);
}
}
此部分代码为打开相机时默认打开前置摄像头CameraInfo.CAMERA_FACING_BACK为默认打开后置摄像头,CameraInfo.CAMERA_FACING_FRONT前置摄像头
2.照片拍摄takePhoto()方法中:
Bitmapbitmap=BitmapFactory.decodeByteArray(data,0, data.length); timeString=formatDate(); filename="/data/data/com.example.pujiejiaapp/images/" +timeString+".jpg"; photo=timeString+".jpg"; Filefile=newFile(filename); booleancreateNewFile=file.createNewFile(); FileOutputStreamoutStream=newFileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.JPEG,60,outStream);
此部分代码为将拍摄到的图片保存为以bitmap格式保存在指定的目录下
3.开子线程用于倒计时拍摄
publicvoidrun(){
while(!stopThread){
try{
Thread.sleep(1000);
}catch(InterruptedExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
cameratime--;
mHandler.sendEmptyMessage(222);
if(cameratime<=0){
break;
}
}
}
希望大家理解核心代码的详细注释,欢迎提供意见,希望能给大家带来帮助,谢谢!